package smartkv.client.workloads.ReportGenerator.Formats; import java.awt.Color; import java.awt.GradientPaint; import java.io.File; import java.io.IOException; import java.util.List; import org.apache.commons.math3.stat.Frequency; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis; import org.jfree.chart.axis.CategoryLabelPositions; import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.ValueMarker; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.category.StackedBarRenderer; import org.jfree.chart.title.LegendTitle; import org.jfree.data.category.CategoryDataset; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jfree.ui.RectangleEdge; import smartkv.client.workloads.ActivityEvent; import smartkv.client.workloads.RequestLogEntry; import smartkv.client.workloads.ReportGenerator.Stats; import smartkv.client.workloads.ReportGenerator.StatsCreator; import smartkv.client.workloads.ReportGenerator.WorkLoadResults; import smartkv.server.RequestType.SuperType; import com.google.common.collect.Iterators; import com.google.common.collect.PeekingIterator; public class GenerateGraphics { public static JFreeChart createReadWriteThroughPut(WorkLoadResults wr, boolean writeEventLabels){ List<List<RequestLogEntry>> writesPerSecond = wr.getRequestsPerIntervalWithEmptyIntervals(1000, SuperType.WRITE); List<List<RequestLogEntry>> readsPerSecond = wr.getRequestsPerIntervalWithEmptyIntervals(1000, SuperType.READ); int writes =0; final XYSeries writesSeries = new XYSeries("Writes"); for (int i =0 ; i < writesPerSecond.size() ; i++){ List<RequestLogEntry> list = writesPerSecond.get(i); writesSeries.add(i, list.size()); writes += list.size(); } System.out.println("writes: - Total:" + wr.getWrites().size() + " ; PerSecond: "+ writes); int reads = 0; final XYSeries readSeries = new XYSeries("Read Throughput"); { for (int i =0 ; i < readsPerSecond.size() ; i++){ List<RequestLogEntry> list = readsPerSecond.get(i); readSeries.add(i, list.size()); reads += list.size(); } System.out.println("reads - Total: " + wr.getReads().size() + " ; PerSecond: " + reads); } final XYSeriesCollection data = new XYSeriesCollection(writesSeries); data.addSeries(readSeries); final JFreeChart chart = ChartFactory.createXYLineChart( "", "Time (seconds)", "#Requests", data, PlotOrientation.VERTICAL, true, true, false ); long timeStartReference = wr.getTimeZero(); XYPlot plot = (XYPlot) chart.getPlot(); //Set events : for (ActivityEvent e : wr.getActivityLog()){ switch(e.getType()){ /* case LINK_ADDED: if (writeEventLabels) addMarker(timeStartReference, e, plot, Color.GREEN, null,true); break; case LINK_REMOVED: if (writeEventLabels) addMarker(timeStartReference, e, plot, Color.CYAN, null,true); break; */ case NEW_TOPOLOGY_INSTANCE: if (writeEventLabels) addMarker(timeStartReference, e, plot, Color.GREEN, null, true); break; case START_NETWORK: //addIntervarlMarker(timeStartReference,e.getTimeStart(), e.getTimeEnd(), plot, Color.DARK_GRAY, (float) 0.1, "Network Init"); addMarker(timeStartReference, e, plot, Color.black, "IB", true); addMarker(timeStartReference, e, plot, Color.black, "IE", false); break; case STOP_NETWORK: //addIntervarlMarker(timeStartReference, e.getTimeStart(), e.getTimeEnd() + 100000, plot, Color.DARK_GRAY, (float) 0.9, "Network stopped"); addMarker(timeStartReference, e, plot, Color.BLACK, "S",true); break; case REMOVING_LINKS: addMarker(timeStartReference, e, plot, Color.pink, "RB", true); addMarker(timeStartReference, e, plot, Color.pink, "RE", false); case SWITCH_TURN_OFF: addMarker(timeStartReference, e, plot, Color.MAGENTA, "TB", true); addMarker(timeStartReference, e, plot, Color.MAGENTA, "TE", false); //addIntervarlMarker(timeStartReference, e.getTimeStart(), e.getTimeEnd(), plot, Color.DARK_GRAY, (float) 0.5, "Start Removing Links"); break; default: } } plot.setBackgroundPaint(Color.WHITE); return chart; } public static JFreeChart createSize(WorkLoadResults wr, boolean writeEventLabels){ List<List<RequestLogEntry>> writesPerSecond = wr.getRequestsPerIntervalWithEmptyIntervals(1000, SuperType.WRITE); List<List<RequestLogEntry>> readsPerSecond = wr.getRequestsPerIntervalWithEmptyIntervals(1000, SuperType.READ); int writes =0; final XYSeries writesSeries = new XYSeries("Write Request Total size"); for (int i =0 ; i < writesPerSecond.size() ; i++){ List<RequestLogEntry> list = writesPerSecond.get(i); Stats s = StatsCreator.writeRequestSize( new WorkLoadResults(list, wr.getActivityLog())); int size=0; for (RequestLogEntry l : list){ size += l.getSizeOfRequest(); } writesSeries.add(i,size); } int reads = 0; final XYSeries readSeries = new XYSeries("Read Response Total size"); { for (int i =0 ; i < readsPerSecond.size() ; i++){ List<RequestLogEntry> list = readsPerSecond.get(i); Stats s = StatsCreator.readResponseSize( new WorkLoadResults(list, wr.getActivityLog())); int size = 0; for (RequestLogEntry l : list){ size += l.getSizeOfResponse(); } readSeries.add(i,size); } } final XYSeriesCollection data = new XYSeriesCollection(writesSeries); data.addSeries(readSeries); final JFreeChart chart = ChartFactory.createXYLineChart( "", "Time (seconds)", "#size in bytes", data, PlotOrientation.VERTICAL, true, true, false ); long timeStartReference = wr.getTimeZero(); XYPlot plot = (XYPlot) chart.getPlot(); //Set events : for (ActivityEvent e : wr.getActivityLog()){ switch(e.getType()){ case LINK_ADDED: if (writeEventLabels) addMarker(timeStartReference, e, plot, Color.GREEN, null,true); break; case LINK_REMOVED: if (writeEventLabels) addMarker(timeStartReference, e, plot, Color.CYAN, null,true); break; case NEW_TOPOLOGY_INSTANCE: if (writeEventLabels) addMarker(timeStartReference, e, plot, Color.YELLOW,null, true); break; case START_NETWORK: //addIntervarlMarker(timeStartReference,e.getTimeStart(), e.getTimeEnd(), plot, Color.DARK_GRAY, (float) 0.1, "Network Init"); addMarker(timeStartReference, e, plot, Color.black, "IB", true); addMarker(timeStartReference, e, plot, Color.black, "IE", false); break; case STOP_NETWORK: //addIntervarlMarker(timeStartReference, e.getTimeStart(), e.getTimeEnd() + 100000, plot, Color.DARK_GRAY, (float) 0.9, "Network stopped"); addMarker(timeStartReference, e, plot, Color.BLACK, "S",true); break; case REMOVING_LINKS: addMarker(timeStartReference, e, plot, Color.pink, "RB", true); addMarker(timeStartReference, e, plot, Color.pink, "RE", false); case SWITCH_TURN_OFF: addMarker(timeStartReference, e, plot, Color.MAGENTA, "TB", true); addMarker(timeStartReference, e, plot, Color.MAGENTA, "TE", false); //addIntervarlMarker(timeStartReference, e.getTimeStart(), e.getTimeEnd(), plot, Color.DARK_GRAY, (float) 0.5, "Start Removing Links"); break; } } plot.setBackgroundPaint(Color.WHITE); return chart; } public static JFreeChart createSizeM(WorkLoadResults wr, boolean writeEventLabels){ List<List<RequestLogEntry>> writesPerSecond = wr.getRequestsPerIntervalWithEmptyIntervals(1000, SuperType.WRITE); List<List<RequestLogEntry>> readsPerSecond = wr.getRequestsPerIntervalWithEmptyIntervals(1000, SuperType.READ); int writes =0; final XYSeries writesSeries = new XYSeries("Write Request mean size"); for (int i =0 ; i < writesPerSecond.size() ; i++){ List<RequestLogEntry> list = writesPerSecond.get(i); Stats s = StatsCreator.writeRequestSize( new WorkLoadResults(list, wr.getActivityLog())); int size=0; writesSeries.add(i,s.dstats.getMean()/1024); } int reads = 0; final XYSeries readSeries = new XYSeries("Read Response Mean size"); { for (int i =0 ; i < readsPerSecond.size() ; i++){ List<RequestLogEntry> list = readsPerSecond.get(i); Stats s = StatsCreator.readResponseSize( new WorkLoadResults(list, wr.getActivityLog())); int size = 0; readSeries.add(i,s.dstats.getMean() / 1024); } } final XYSeriesCollection data = new XYSeriesCollection(writesSeries); data.addSeries(readSeries); final JFreeChart chart = ChartFactory.createXYLineChart( "", "Time (s)", "Mean Message Size (kB)", data, PlotOrientation.VERTICAL, true, true, false ); long timeStartReference = wr.getTimeZero(); XYPlot plot = (XYPlot) chart.getPlot(); LegendTitle t = chart.getLegend(); t.setPosition(RectangleEdge.TOP); //plot.getRangeAxis().setRange(0, 80); //plot.getDomainAxis().setRange(600, 1200); //Set events : for (ActivityEvent e : wr.getActivityLog()){ switch(e.getType()){ /* case LINK_ADDED: if (writeEventLabels) addMarker(timeStartReference, e, plot, Color.GREEN, null,true); break; case LINK_REMOVED: if (writeEventLabels) addMarker(timeStartReference, e, plot, Color.CYAN, null,true); break; */ case NEW_TOPOLOGY_INSTANCE: if (writeEventLabels) addMarker(timeStartReference, e, plot, Color.GREEN,null, true); break; case START_NETWORK: //addIntervarlMarker(timeStartReference,e.getTimeStart(), e.getTimeEnd(), plot, Color.DARK_GRAY, (float) 0.1, "Network Init"); // addMarker(timeStartReference, e, plot, Color.black, "IB", true); // addMarker(timeStartReference, e, plot, Color.black, "IE", false); break; case STOP_NETWORK: //addIntervarlMarker(timeStartReference, e.getTimeStart(), e.getTimeEnd() + 100000, plot, Color.DARK_GRAY, (float) 0.9, "Network stopped"); addMarker(timeStartReference, e, plot, Color.BLACK, "S",true); break; case REMOVING_LINKS: //addMarker(timeStartReference, e, plot, Color.pink, "RB", true); //addMarker(timeStartReference, e, plot, Color.pink, "RE", false); break; case SWITCH_TURN_OFF: //addMarker(timeStartReference, e, plot, Color.MAGENTA, "TB", true); //addMarker(timeStartReference, e, plot, Color.MAGENTA, "TE", false); //addIntervarlMarker(timeStartReference, e.getTimeStart(), e.getTimeEnd(), plot, Color.DARK_GRAY, (float) 0.5, "Start Removing Links"); break; default: } } plot.setBackgroundPaint(Color.WHITE); return chart; } public static void saveChart(String path, JFreeChart chart, int width, int weight) throws IOException{ File f = new File(path); ChartUtilities.saveChartAsPNG(f, chart, width, weight); } /** * @param timeStartReference * @param e * @return */ private static void addMarker(long timeStartReference, ActivityEvent e, XYPlot plot , Color c, String label, boolean beginning) { ValueMarker marker = new ValueMarker( beginning ? (e.timeStart - timeStartReference) /1000.0: (e.timeEnd - timeStartReference) / 1000.0); marker.setAlpha((float) 1); marker.setPaint(c); /*if (label != null) { marker.setLabel(label); }*/ plot.addDomainMarker(marker); } /* public static class Solve extends StandardCategoryItemLabelGenerator { @Override public String generateLabel(CategoryDataset dataset, int row, int column){ DefaultCategoryDataset s = new DefaultCategoryDataset(); s.addValue(dataset.getValue(row, column).doubleValue() * 100.0, "P[x <= X] ", ""); return super.generateLabel(s, row, column); //new DefaultCategoryDataset(dataset.getValue(row, column).doubleValue() * 100, dataset.getRowKey(row), dataset.getColumnKey(column)); } }*/ public static JFreeChart getChartFromFreq(Frequency freq, String Title, String x, String y){ DefaultCategoryDataset dataset = getDataSetFromFrequency(freq); // create the chart... final JFreeChart chart = ChartFactory.createBarChart( Title, // chart title x, // domain axis label y, // range axis label dataset, // 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); // get a reference to the plot for further customisation... final CategoryPlot plot = chart.getCategoryPlot(); plot.setBackgroundPaint(Color.lightGray); plot.setDomainGridlinePaint(Color.white); plot.setRangeGridlinePaint(Color.white); StackedBarRenderer renderer = new StackedBarRenderer(false); /* renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); renderer.setBaseItemLabelsVisible(true); chart.getCategoryPlot().setRenderer(renderer); */ // set the range axis to display integers only... //final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis(); //rangeAxis.setStandaepordTickUnits(NumberAxis.createIntegerTickUnits()); // disable bar outlines... chart.getCategoryPlot().setRenderer(renderer); renderer.setDrawBarOutline(false); // set up gradient paints for series... /*final GradientPaint gp1 = new GradientPaint( 0.0f, 0.0f, Color.green, 0.0f, 0.0f, Color.lightGray ); final GradientPaint gp2 = new GradientPaint( 0.0f, 0.0f, Color.red, 0.0f, 0.0f, Color.lightGray );*/ renderer.setSeriesPaint(0, Color.BLUE); //renderer.setSeriesPaint(1, gp1); //renderer.setSeriesPaint(2, gp2); final CategoryAxis domainAxis = plot.getDomainAxis(); domainAxis.setCategoryLabelPositions( CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 6.0) ); // OPTIONAL CUSTOMISATION COMPLETED. return chart; } /** * @param freq */ private static DefaultCategoryDataset getDataSetFromFrequency(Frequency freq) { DefaultCategoryDataset dataset = new DefaultCategoryDataset(); PeekingIterator<Comparable<?>> it = Iterators.peekingIterator(freq.valuesIterator()); double count=0, pct=0, cumPct =0; while (it.hasNext()){ Comparable<?> value = it.next(); count = freq.getCount(value); pct = freq.getPct(value); cumPct = freq.getCumPct(value); double max_value = 0.05 - pct; Comparable<?> lastValueInInterval =null; //Represents that we have now a set since the percentage of the value is small (less than max_value) while (it.hasNext() && (max_value - freq.getPct(it.peek()) ) >= 0 ){ Comparable<?> nextValue = it.next(); max_value -= freq.getPct(nextValue); count += freq.getCount(nextValue); pct += freq.getPct(nextValue); cumPct += freq.getPct(nextValue); lastValueInInterval = nextValue; } String category = lastValueInInterval == null ? value.toString() : value.toString() + "-" + lastValueInInterval.toString() ; dataset.addValue(cumPct, "P[x <= X] ", category); //dataset.addValue(pct, "P[X] ", category); } return dataset; } }