Java tutorial
/* ============================================================================ * AMES Wholesale Power Market Test Bed (Java): A Free Open-Source Test-Bed * for the Agent-based Modeling of Electricity Systems * ============================================================================ * * (C) Copyright 2008, by Hongyan Li, Junjie Sun, and Leigh Tesfatsion * * Homepage: http://www.econ.iastate.edu/tesfatsi/AMESMarketHome.htm * * LICENSING TERMS * The AMES Market Package is licensed by the copyright holders (Junjie Sun, * Hongyan Li, and Leigh Tesfatsion) as free open-source software under the * terms of the GNU General Public License (GPL). Anyone who is interested is * allowed to view, modify, and/or improve upon the code used to produce this * package, but any software generated using all or part of this code must be * released as free open-source software in turn. The GNU GPL can be viewed in * its entirety as in the following site: http://www.gnu.org/licenses/gpl.html * * * * * JFreeChart is a free chart library for the Java(tm) platform * JFreeChart Project Info: http://www.jfree.org/jfreechart/index.html */ /* * SplitChart.java * * Created on 2007 3 12 , 10:52 * * to change this template, choose Tools | Template Manager * and open the template in the editor. */ package Output; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.text.DecimalFormat; import java.util.ArrayList; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JSplitPane; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis; import org.jfree.chart.axis.CategoryLabelPositions; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.labels.CustomXYToolTipGenerator; import org.jfree.chart.labels.StandardXYToolTipGenerator; import org.jfree.chart.labels.XYToolTipGenerator; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.Plot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.category.BarRenderer; import org.jfree.chart.renderer.category.CategoryItemRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.chart.title.TextTitle; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import AMESGUIFrame.AMESFrame; import amesmarket.Support; public class SplitChart extends JFrame { /** Creates a new instance of SplitChart */ public SplitChart() { super("Output Chart View"); } public void createAndShowGUI() { //Create and set up the window. this.chartPanel = new ChartPanel(this.chart); int[] indexNull = new int[0]; this.drawGeneratorCommitmentWithTrueCostData("", 0, 0, 0, indexNull); SelectPanel selectPanel = new SelectPanel(this.amesFrame, false, null, this); //Provide minimum sizes for the two components in the split pane selectPanel.setMinimumSize(new Dimension(100, 50)); this.chartPanel.setMinimumSize(new Dimension(100, 30)); JSplitPane splitPane = new JSplitPane(); splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT); splitPane.setLeftComponent(selectPanel); splitPane.setRightComponent(this.chartPanel); splitPane.setOneTouchExpandable(true); splitPane.setDividerLocation(430); //Add the split pane to this frame this.getContentPane().add(splitPane); //Display the window. this.pack(); this.setVisible(true); } public void drawGridLinesData(int[] selectIndex) { DefaultCategoryDataset dataset3D = new DefaultCategoryDataset(); Object[][] branchData = this.amesFrame.getBranchData(); int iBranchNumber = branchData.length; if ((selectIndex.length < 1) || (selectIndex[0] == 0)) { for (int i = 0; i < iBranchNumber; i++) { String branchName = (String) branchData[i][0]; dataset3D.addValue((Math.round(Support.parseDouble(branchData[i][3].toString()) * 1000)) / 1000.0, "Capacities (MWs)", branchName); } } else { int iDataNumber = selectIndex.length; for (int i = 0; i < iDataNumber; i++) { String branchName = (String) branchData[selectIndex[i] - 1][0]; dataset3D.addValue( (Math.round(Support.parseDouble(branchData[selectIndex[i] - 1][3].toString()) * 1000)) / 1000.0, "Capacities (MWs)", branchName); } } this.chart = ChartFactory.createBarChart3D("Branch Max Capacities", // chart title "", // domain axis label "Capacities (MWs)", // range axis label dataset3D, // data PlotOrientation.VERTICAL, // orientation true, // include legend true, // tooltips false // urls ); final CategoryPlot plot = this.chart.getCategoryPlot(); final CategoryAxis axis = plot.getDomainAxis(); axis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 8.0)); final CategoryItemRenderer renderer = plot.getRenderer(); renderer.setItemLabelsVisible(true); final BarRenderer r = (BarRenderer) renderer; r.setMaximumBarWidth(0.05); this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawGeneratorData(int[] selectIndex) { DefaultCategoryDataset dataset3D = new DefaultCategoryDataset(); String xLabel = "Power (MWs)"; this.dataset = new XYSeriesCollection(); boolean bDraw3D = true; Object[][] genData = this.amesFrame.getGeneratorData(); int iGenNumber = genData.length; if ((selectIndex.length < 1) || (selectIndex[0] == 0)) { for (int i = 0; i < iGenNumber; i++) { String genName = (String) genData[i][0]; dataset3D.addValue((Math.round(Support.parseDouble(genData[i][6].toString()) * 1000)) / 1000.0, "capL (MW)", genName); dataset3D.addValue((Math.round(Support.parseDouble(genData[i][7].toString()) * 1000)) / 1000.0, "capU (MW)", genName); } } else { int iDataNumber = selectIndex.length; if (iDataNumber > 1) { for (int i = 0; i < iDataNumber; i++) { String genName = (String) genData[selectIndex[i] - 1][0]; dataset3D.addValue( (Math.round(Support.parseDouble(genData[selectIndex[i] - 1][6].toString()) * 1000)) / 1000.0, "capL (MW)", genName); dataset3D.addValue( (Math.round(Support.parseDouble(genData[selectIndex[i] - 1][7].toString()) * 1000)) / 1000.0, "capU (MW)", genName); } } else { // only select one GenCo XYSeries series = new XYSeries("True"); int genIndex = selectIndex[0] - 1; this.chartTitle = (String) genData[genIndex][0] + "'s True Marginal Cost Function"; double da = Support.parseDouble(genData[genIndex][4].toString()); double db = Support.parseDouble(genData[genIndex][5].toString()); double dMinCap = Support.parseDouble(genData[genIndex][6].toString()); double dMaxCap = Support.parseDouble(genData[genIndex][7].toString()); double dStart = da + (2.0 * db * dMinCap); double dEnd = da + (2.0 * db * dMaxCap); series.add(dMinCap, dStart); series.add(dMaxCap, dEnd); this.dataset.addSeries(series); bDraw3D = false; } } if (bDraw3D) { this.chart = ChartFactory.createBarChart3D("GenCo Lower and Upper Operating Limits", // chart title "", // domain axis label "Capacities (MWs)", // range axis label dataset3D, // data PlotOrientation.VERTICAL, // orientation true, // include legend true, // tooltips false // urls ); final CategoryPlot plot = this.chart.getCategoryPlot(); final CategoryAxis axis = plot.getDomainAxis(); axis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 8.0)); final CategoryItemRenderer renderer = plot.getRenderer(); renderer.setItemLabelsVisible(true); final BarRenderer r = (BarRenderer) renderer; r.setMaximumBarWidth(0.05); } else { // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title xLabel, // x axis label "Price ($/MWh)", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); renderer.setToolTipGenerator(generator); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); } this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawLSEFixedDemandData(int[] selectIndex) { this.chartTitle = "24 Hour LSE Fixed Demand (Load Profile)"; Object[][] lseData = this.amesFrame.getLSEData(); this.dataset = new XYSeriesCollection(); DefaultCategoryDataset dataset3D = new DefaultCategoryDataset(); if ((selectIndex.length < 1) || (selectIndex[0] == 0)) { for (Object[] element : lseData) { XYSeries series = new XYSeries((String) element[0]); for (int j = 0; j < 24; j++) { series.add(j, Support.parseDouble(element[j + 3].toString())); } this.dataset.addSeries(series); } } else { int iDataNumber = selectIndex.length; for (int i = 0; i < iDataNumber; i++) { XYSeries series = new XYSeries((String) lseData[selectIndex[i] - 1][0]); for (int j = 0; j < 24; j++) { if (iDataNumber == 1) { String temp = " " + j; dataset3D.addValue(Support.parseDouble(lseData[selectIndex[i] - 1][j + 3].toString()), lseData[selectIndex[i] - 1][0].toString(), temp); } else { series.add(j, Support.parseDouble(lseData[selectIndex[i] - 1][j + 3].toString())); } } if (iDataNumber != 1) { this.dataset.addSeries(series); } } } if ((selectIndex.length == 1) && (selectIndex[0] != 0)) { this.chartTitle = (String) (lseData[selectIndex[0] - 1][0]); this.chartTitle = this.chartTitle + " 24 Hour Fixed Demand (Load Profile)"; this.chart = ChartFactory.createBarChart3D(this.chartTitle, // chart title "Hour", // domain axis label "Power (MWs)", // range axis label dataset3D, // data PlotOrientation.VERTICAL, // orientation true, // include legend true, // tooltips false // urls ); final CategoryPlot plot = this.chart.getCategoryPlot(); final CategoryAxis axis = plot.getDomainAxis(); axis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 8.0)); final CategoryItemRenderer renderer = plot.getRenderer(); renderer.setItemLabelsVisible(true); final BarRenderer r = (BarRenderer) renderer; r.setMaximumBarWidth(0.05); } else { // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title "Hour", // x axis label "Power (MWs)", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); renderer.setToolTipGenerator(generator); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); xAxis.setRange(0, 23.5); } this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawGeneratorCommitmentWithTrueCostData(String outputTimeTypeSelect, int iStartTime, int iEndTime, int iDayHour, int[] selectIndex) { String[] names = { "GenCo Name", "Hour", "Power (MW)" }; this.chartTitle = "GenCo Commitments (Benchmark)"; ArrayList genAgentCommitmentWithTrueCost = this.amesFrame.getAMESMarket() .getGenAgentCommitmentWithTrueCost(); boolean draw3DChart = false; this.dataset = new XYSeriesCollection(); DefaultCategoryDataset dataset3D = new DefaultCategoryDataset(); Object[][] genData = this.amesFrame.getGeneratorData(); int iGenNumber = genData.length; if ((selectIndex.length < 1) || (selectIndex[0] == 0)) { double[][] genCommitmentWithTrueCost = (double[][]) genAgentCommitmentWithTrueCost.get(0); for (int j = 0; j < iGenNumber; j++) { XYSeries series = new XYSeries((String) genData[j][0]); for (int i = 0; i < 24; i++) { series.add(i, (Math.round(genCommitmentWithTrueCost[i][j] * 1000)) / 1000.0); } this.dataset.addSeries(series); } } else { int iDataNumber = selectIndex.length; int iField = names.length; double[][] genCommitmentWithTrueCost = (double[][]) genAgentCommitmentWithTrueCost.get(0); for (int j = 0; j < iDataNumber; j++) { XYSeries series = new XYSeries((String) genData[selectIndex[j] - 1][0]); for (int i = 0; i < 24; i++) { series.add(i, (Math.round(genCommitmentWithTrueCost[i][selectIndex[j] - 1] * 1000)) / 1000.0); } this.dataset.addSeries(series); } } // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title "Hour", // x axis label "Power (MWs)", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART... this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); renderer.setToolTipGenerator(generator); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); xAxis.setRange(0, 23.5); this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawGeneratorProfitWithTrueCostData(String outputTimeTypeSelect, int iStartTime, int iEndTime, int iDayHour, int[] selectIndex, boolean bProfit) { if (bProfit) { this.chartTitle = "GenCo Profits (Benchmark)"; } else { this.chartTitle = "GenCo Net Earnings (Benchmark)"; } ArrayList genAgentProfitWithTrueCost = this.amesFrame.getAMESMarket() .getGenAgentProfitAndNetGainWithTrueCost(); boolean draw3DChart = false; this.dataset = new XYSeriesCollection(); DefaultCategoryDataset dataset3D = new DefaultCategoryDataset(); Object[][] genData = this.amesFrame.getGeneratorData(); int iGenNumber = genData.length; if ((selectIndex.length < 1) || (selectIndex[0] == 0)) { double[][] genProfitWithTrueCost = (double[][]) genAgentProfitWithTrueCost.get(0); for (int j = 0; j < iGenNumber; j++) { XYSeries series; /* = new XYSeries((String)genData[j][0]+" Hourly Profits"); for(int i=0; i<24; i++) { series.add(i, (double)(Math.round(genProfitWithTrueCost[j][i+3]*1000))/1000.0); } dataset.addSeries(series); series = new XYSeries((String)genData[j][0]+" Daily Profits"); double sum=0.0; for(int i=0; i<24; i++) { sum+=genProfitWithTrueCost[j][i+3]; series.add(i, (double)(Math.round(sum*1000))/1000.0); } dataset.addSeries(series); */ series = new XYSeries((String) genData[j][0]); for (int i = 0; i < 24; i++) { if (bProfit) { series.add(i, (Math.round(genProfitWithTrueCost[j][i + 3] * 1000)) / 1000.0); } else { series.add(i, (Math.round(genProfitWithTrueCost[j][i + 27] * 1000)) / 1000.0); } } this.dataset.addSeries(series); /* series = new XYSeries((String)genData[j][0]+" Daily Net Earnings"); double sum=0.0; for(int i=0; i<24; i++) { sum+=genProfitWithTrueCost[j][i+27]; series.add(i, (double)(Math.round(sum*1000))/1000.0); } dataset.addSeries(series); series = new XYSeries((String)genData[j][0]+" Hourly Revenue"); for(int i=0; i<24; i++) { series.add(i, (double)(Math.round(genProfitWithTrueCost[j][i+51]*1000))/1000.0); } dataset.addSeries(series); series = new XYSeries((String)genData[j][0]+" Daily Revenue"); sum=0.0; for(int i=0; i<24; i++) { sum+=genProfitWithTrueCost[j][i+51]; series.add(i, (double)(Math.round(sum*1000))/1000.0); } dataset.addSeries(series); */ } } else { int iDataNumber = selectIndex.length; double[][] genProfitWithTrueCost = (double[][]) genAgentProfitWithTrueCost.get(0); for (int j = 0; j < iDataNumber; j++) { XYSeries series; /* = new XYSeries((String)genData[selectIndex[j]-1][0]+" Houely Profits"); for(int i=0; i<24; i++) { series.add(i, (double)(Math.round(genProfitWithTrueCost[selectIndex[j]-1][i+3]*1000))/1000.0); } dataset.addSeries(series); series = new XYSeries((String)genData[selectIndex[j]-1][0]+" Daily Profits"); double sum=0.0; for(int i=0; i<24; i++) { sum+=genProfitWithTrueCost[selectIndex[j]-1][i+3]; series.add(i, (double)(Math.round(sum*1000))/1000.0); } dataset.addSeries(series); */ series = new XYSeries((String) genData[selectIndex[j] - 1][0]); for (int i = 0; i < 24; i++) { if (bProfit) { series.add(i, (Math.round(genProfitWithTrueCost[selectIndex[j] - 1][i + 3] * 1000)) / 1000.0); } else { series.add(i, (Math.round(genProfitWithTrueCost[selectIndex[j] - 1][i + 27] * 1000)) / 1000.0); } } this.dataset.addSeries(series); /* series = new XYSeries((String)genData[selectIndex[j]-1][0]+" Daily Net Earnings"); sum=0.0; for(int i=0; i<24; i++) { sum+=genProfitWithTrueCost[selectIndex[j]-1][i+27]; series.add(i, (double)(Math.round(sum*1000))/1000.0); } dataset.addSeries(series); series = new XYSeries((String)genData[selectIndex[j]-1][0]+" Hourly Revenue"); for(int i=0; i<24; i++) { series.add(i, (double)(Math.round(genProfitWithTrueCost[selectIndex[j]-1][i+51]*1000))/1000.0); } dataset.addSeries(series); series = new XYSeries((String)genData[selectIndex[j]-1][0]+" Daily Revenue"); sum=0.0; for(int i=0; i<24; i++) { sum+=genProfitWithTrueCost[selectIndex[j]-1][i+51]; series.add(i, (double)(Math.round(sum*1000))/1000.0); } dataset.addSeries(series); */ } } // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title "Hour", // x axis label "Money ($/H)", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART... this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); renderer.setToolTipGenerator(generator); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); xAxis.setRange(0, 23.5); this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawPSDemandDispatchWithTrueCostData(String outputTimeTypeSelect, int iStartTime, int iEndTime, int iDayHour, int[] selectIndex) { String[] names = { "LSE Name", "Hour", "c ($/MWh)", "d ($/MW2h)", "SLMax (MW)", "Price-Sensitive Demand (MW)" }; Object[][][] lsePriceSensitiveData = this.amesFrame.getLSEPriceSensitiveDemandData(); Object[][] lseHybridData = this.amesFrame.getLSEHybridDemandData(); int iLSENumber = lsePriceSensitiveData.length; ArrayList LMPWithTrueCost = this.amesFrame.getAMESMarket().getLMPWithTrueCost(); double[][] lmp = (double[][]) LMPWithTrueCost.get(0); ArrayList priceSensitiveWithTrueCost = this.amesFrame.getAMESMarket() .getLSEAgentPriceSensitiveDemandWithTrueCost(); this.chartTitle = "LSE Price-Sensitive Demand Function \nand Cleared Point (Benchmark)"; String xLabel = "Power (MWs)"; this.dataset = new XYSeriesCollection(); if (selectIndex.length < 1) { JOptionPane.showMessageDialog(this, "No LSE is selected!", "Error Message", JOptionPane.ERROR_MESSAGE); return; } double[][] lsePS = (double[][]) priceSensitiveWithTrueCost.get(0); int lseIndex = selectIndex[0]; int lseAtBus = Integer.parseInt(lseHybridData[lseIndex][2].toString()); double busLMP = lmp[iDayHour][lseAtBus - 1]; this.chartTitle = this.chartTitle + "\n " + lsePriceSensitiveData[lseIndex][0][0] + " Hour " + iDayHour; XYSeries series = new XYSeries("Cleared Point"); int psLoadIndex = 0; // Get the psLoadIndex for (int k = 0; k < selectIndex[0]; k++) { int hourlyFlag = Integer.parseInt(lseHybridData[k][iDayHour + 3].toString()); if ((hourlyFlag & 2) == 2) { psLoadIndex++; } } double dStart = 0; double dEnd = 0; int hourlyLoadHybridFlagByLSE = Integer.parseInt(lseHybridData[selectIndex[0]][iDayHour + 3].toString()); if ((hourlyLoadHybridFlagByLSE & 2) == 2) { dStart = lsePS[iDayHour][psLoadIndex]; } double c = Support.parseDouble(lsePriceSensitiveData[lseIndex][iDayHour][4].toString()); double d = Support.parseDouble(lsePriceSensitiveData[lseIndex][iDayHour][5].toString()); double slMax = Support.parseDouble(lsePriceSensitiveData[lseIndex][iDayHour][6].toString()); dEnd = c - (2.0 * d * dStart); series.add(dStart, busLMP); this.dataset.addSeries(series); series = new XYSeries("Price-Sensitive Demand Function"); dEnd = c - (2.0 * d * slMax); series.add(0, c); series.add(slMax, dEnd); this.dataset.addSeries(series); // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title xLabel, // x axis label "Price ($/MWh)", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); renderer.setToolTipGenerator(generator); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawLSESurplusWithTrueCostData(String outputTimeTypeSelect, int iStartTime, int iEndTime, int iDayHour, int[] selectIndex) { this.chartTitle = "LSE Net Earnings (Benchmark)"; ArrayList LSEAgentSurplusWithTrueCost = this.amesFrame.getAMESMarket().getLSEAgentSurplusWithTrueCost(); Object[][] lseHybridData = this.amesFrame.getLSEHybridDemandData(); int iLSENumber = lseHybridData.length; boolean draw3DChart = false; this.dataset = new XYSeriesCollection(); DefaultCategoryDataset dataset3D = new DefaultCategoryDataset(); if ((selectIndex.length < 1) || (selectIndex[0] == 0)) { double[][] surplus = (double[][]) LSEAgentSurplusWithTrueCost.get(0); for (int j = 0; j < iLSENumber; j++) { XYSeries series = new XYSeries((String) lseHybridData[j][0]); for (int i = 0; i < 24; i++) { series.add(i, (Math.round(surplus[j][i + 1] * 1000)) / 1000.0); } this.dataset.addSeries(series); /* series = new XYSeries((String)lseHybridData[j][0]+" Total"); double sum=0.0; for(int i=0; i<24; i++) { sum+=surplus[j][i+1]; series.add(i, (double)(Math.round(sum*1000))/1000.0); } dataset.addSeries(series); */ } } else { int iDataNumber = selectIndex.length; double[][] surplus = (double[][]) LSEAgentSurplusWithTrueCost.get(0); for (int j = 0; j < iDataNumber; j++) { XYSeries series = new XYSeries((String) lseHybridData[selectIndex[j] - 1][0]); for (int i = 0; i < 24; i++) { series.add(i, (Math.round(surplus[selectIndex[j] - 1][i + 1] * 1000)) / 1000.0); } this.dataset.addSeries(series); /* series = new XYSeries((String)lseHybridData[selectIndex[j]-1][0]+" Total"); double sum=0.0; for(int i=0; i<24; i++) { sum+=surplus[selectIndex[j]-1][i+1]; series.add(i, (double)(Math.round(sum*1000))/1000.0); } dataset.addSeries(series); */ } } // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title "Hour", // x axis label "Net Earnings ($)", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART... this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); renderer.setToolTipGenerator(generator); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); xAxis.setRange(0, 23.5); this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawNodeLMPWithTrueCostData(String outputTimeTypeSelect, int iStartTime, int iEndTime, int iDayHour, int[] selectIndex) { String[] names = { "Bus Name", " Hour", " LMP" }; this.chartTitle = "Locational Marginal Prices (Benchmark)"; ArrayList LMPWithTrueCost = this.amesFrame.getAMESMarket().getLMPWithTrueCost(); String[] nodeName = this.amesFrame.getNodeNameData(); int iNodeNumber = nodeName.length; boolean draw3DChart = false; this.dataset = new XYSeriesCollection(); DefaultCategoryDataset dataset3D = new DefaultCategoryDataset(); if ((selectIndex.length < 1) || (selectIndex[0] == 0)) { double[][] lmp = (double[][]) LMPWithTrueCost.get(0); for (int j = 0; j < iNodeNumber; j++) { XYSeries series = new XYSeries(nodeName[j]); for (int i = 0; i < 24; i++) { series.add(i, (Math.round(lmp[i][j] * 1000)) / 1000.0); } this.dataset.addSeries(series); } } else { int iDataNumber = selectIndex.length; int iField = names.length; double[][] lmp = (double[][]) LMPWithTrueCost.get(0); for (int j = 0; j < iDataNumber; j++) { XYSeries series = new XYSeries(nodeName[selectIndex[j] - 1]); for (int i = 0; i < 24; i++) { series.add(i, (Math.round(lmp[i][selectIndex[j] - 1] * 1000)) / 1000.0); } this.dataset.addSeries(series); } } // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title "Hour", // x axis label "Price ($/MWh)", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); // NOW DO SOME OPTIONAL CUSTOMIZATION OF THE CHART... this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); renderer.setToolTipGenerator(generator); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); xAxis.setRange(0, 23.5); this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawAggreagtedSupplyAndDemandWithTrueCostData(String outputTimeTypeSelect, int iStartTime, int iEndTime, int iDayHour, int[] selectIndex) { ArrayList genAgentSupplyOfferByDay = this.amesFrame.getAMESMarket().getGenAgentSupplyOfferByDay(); Object[][] genData = this.amesFrame.getGeneratorData(); int iGenNumber = genData.length; double[][] genOfferData = new double[iGenNumber][8]; // a, b, minCap, maxCap, 1/b, a/b, currentPower, currentPrice double[][] offerPrices = new double[iGenNumber * 2][2]; // price, index for (int i = 0; i < iGenNumber; i++) { genOfferData[i][0] = Support.parseDouble(genData[i][4].toString()); genOfferData[i][1] = Support.parseDouble(genData[i][5].toString()); genOfferData[i][2] = Support.parseDouble(genData[i][6].toString()); genOfferData[i][3] = Support.parseDouble(genData[i][7].toString()); genOfferData[i][4] = 1.0 / genOfferData[i][1]; genOfferData[i][5] = genOfferData[i][0] / genOfferData[i][1]; offerPrices[2 * i][0] = genOfferData[i][0] + (2 * genOfferData[i][1] * genOfferData[i][2]); offerPrices[2 * i][1] = 2 * i; offerPrices[(2 * i) + 1][0] = genOfferData[i][0] + (2 * genOfferData[i][1] * genOfferData[i][3]); offerPrices[(2 * i) + 1][1] = (2 * i) + 1; genOfferData[i][6] = genOfferData[i][2]; genOfferData[i][7] = offerPrices[2 * i][0]; } // sort the price of each generator double dTemp = 0; double iTemp = 0; for (int i = 0; i < (2 * iGenNumber); i++) { for (int j = i + 1; j < (2 * iGenNumber); j++) { if (offerPrices[i][0] > offerPrices[j][0]) { dTemp = offerPrices[i][0]; iTemp = offerPrices[i][1]; offerPrices[i][0] = offerPrices[j][0]; offerPrices[i][1] = offerPrices[j][1]; offerPrices[j][0] = dTemp; offerPrices[j][1] = iTemp; } } } double[][] genAggregateOfferDataPoints = new double[(iGenNumber * 2) - 1][4]; // leftPoint(power, price), rightPoint(power, price) int[][] genAggregateOfferCommit = new int[(iGenNumber * 2) - 1][iGenNumber * 2]; // in the first iGenNumber of each row is the index of gen whose output is fixed // in the second iGenNumber of each row is the index of gen whose output is variable // otherwise -1 for (int i = 0; i < ((2 * iGenNumber) - 1); i++) { for (int j = 0; j < (2 * iGenNumber); j++) { genAggregateOfferCommit[i][j] = -1; } } double leftPrice = offerPrices[0][0]; for (int i = 0; i < iGenNumber; i++) { if (leftPrice >= genOfferData[i][7]) { genAggregateOfferDataPoints[0][0] += genOfferData[i][6]; } } for (int i = 0; i < ((2 * iGenNumber) - 1); i++) { genAggregateOfferDataPoints[i][1] = offerPrices[i][0]; genAggregateOfferDataPoints[i][3] = offerPrices[i + 1][0]; if (i > 0) { genAggregateOfferDataPoints[i][0] = genAggregateOfferDataPoints[i - 1][2]; } genAggregateOfferDataPoints[i][2] = genAggregateOfferDataPoints[i][0]; int iIndexFixed = 0; int iIndexVariable = 0; double rightPrice = offerPrices[i + 1][0]; for (int j = 0; j < iGenNumber; j++) { if (rightPrice > genOfferData[j][7]) { if (Math.abs(genOfferData[j][6] - genOfferData[j][3]) < 0.000001) { // already at maxCap genAggregateOfferCommit[i][iIndexFixed++] = j; } else { double power = (rightPrice - genOfferData[j][0]) / (2 * genOfferData[j][1]); genAggregateOfferDataPoints[i][2] += power - genOfferData[j][6]; genAggregateOfferCommit[i][iGenNumber + iIndexVariable] = j; iIndexVariable++; genOfferData[j][7] = rightPrice; genOfferData[j][6] = power; } } } } double HighestGenOfferPrice = genAggregateOfferDataPoints[(iGenNumber * 2) - 2][3]; double HighestGenOfferPower = genAggregateOfferDataPoints[(iGenNumber * 2) - 2][2]; // Demand Object[][][] lsePriceSensitiveData = this.amesFrame.getLSEPriceSensitiveDemandData(); Object[][] lseHybridData = this.amesFrame.getLSEHybridDemandData(); Object[][] lseData = this.amesFrame.getLSEData(); int iLSENumber = lsePriceSensitiveData.length; double[][] lseDemandData = new double[iLSENumber][6]; // c, d, slMax, fixed demand, currentPower, currentPrice double[][] lsePrices = new double[iLSENumber * 2][2]; // price, index int hourlyLoadHybridFlagByLSE = 0; double priceCap = 1000.0; for (int i = 0; i < iLSENumber; i++) { hourlyLoadHybridFlagByLSE = Integer.parseInt(lseHybridData[i][iDayHour + 3].toString()); if ((hourlyLoadHybridFlagByLSE & 2) == 2) { double c = Support.parseDouble(lsePriceSensitiveData[i][iDayHour][4].toString()); double d = Support.parseDouble(lsePriceSensitiveData[i][iDayHour][5].toString()); double slMax = Support.parseDouble(lsePriceSensitiveData[i][iDayHour][6].toString()); lseDemandData[i][0] = c; lseDemandData[i][1] = d; lseDemandData[i][2] = slMax; lseDemandData[i][4] = 0.0; lseDemandData[i][5] = c; lsePrices[2 * i][0] = c; lsePrices[2 * i][1] = 2 * i; lsePrices[(2 * i) + 1][0] = c - (2 * d * slMax); lsePrices[(2 * i) + 1][1] = (2 * i) + 1; } else { lseDemandData[i][0] = 0.0; lseDemandData[i][1] = 0.0; lseDemandData[i][2] = 0.0; lseDemandData[i][4] = 0.0; lseDemandData[i][5] = priceCap; lsePrices[2 * i][0] = priceCap; lsePrices[2 * i][1] = 2 * i; lsePrices[(2 * i) + 1][0] = priceCap; lsePrices[(2 * i) + 1][1] = (2 * i) + 1; } if ((hourlyLoadHybridFlagByLSE & 1) == 1) { // fixed demand lseDemandData[i][3] = Support.parseDouble(lseData[i][iDayHour + 3].toString()); } } // sort the price of each lse for (int i = 0; i < (2 * iLSENumber); i++) { for (int j = i + 1; j < (2 * iLSENumber); j++) { if (lsePrices[i][0] < lsePrices[j][0]) { dTemp = lsePrices[i][0]; iTemp = lsePrices[i][1]; lsePrices[i][0] = lsePrices[j][0]; lsePrices[i][1] = lsePrices[j][1]; lsePrices[j][0] = dTemp; lsePrices[j][1] = iTemp; } } } double[][] lseAggregateDemandDataPoints = new double[(iLSENumber * 2) - 1][4]; // leftPoint(power, price), rightPoint(power, price) int[][] lseAggregateDemandCommit = new int[(iLSENumber * 2) - 1][iLSENumber * 2]; // in the first iLSENumber of each row is the index of LSE whose commit is fixed // in the second iLSENumber of each row is the index of LSE whose commit is variable // otherwise -1 for (int i = 0; i < ((2 * iLSENumber) - 1); i++) { for (int j = 0; j < (2 * iLSENumber); j++) { lseAggregateDemandCommit[i][j] = -1; } } leftPrice = lsePrices[0][0]; for (int i = 0; i < iLSENumber; i++) { lseAggregateDemandDataPoints[0][0] += lseDemandData[i][3]; if (leftPrice <= lseDemandData[i][5]) { lseAggregateDemandDataPoints[0][0] += lseDemandData[i][4]; } } for (int i = 0; i < ((2 * iLSENumber) - 1); i++) { lseAggregateDemandDataPoints[i][1] = lsePrices[i][0]; lseAggregateDemandDataPoints[i][3] = lsePrices[i + 1][0]; if (i > 0) { lseAggregateDemandDataPoints[i][0] = lseAggregateDemandDataPoints[i - 1][2]; } lseAggregateDemandDataPoints[i][2] = lseAggregateDemandDataPoints[i][0]; int iIndexFixed = 0; int iIndexVariable = 0; double rightPrice = lsePrices[i + 1][0]; for (int j = 0; j < iLSENumber; j++) { if (rightPrice < lseDemandData[j][5]) { if (Math.abs(lseDemandData[j][4] - lseDemandData[j][2]) < 0.000001) { // already at slMax lseAggregateDemandCommit[i][iIndexFixed++] = j; } else { double power = (lseDemandData[j][0] - rightPrice) / (2 * lseDemandData[j][1]); lseAggregateDemandDataPoints[i][2] += power - lseDemandData[j][4]; lseAggregateDemandCommit[i][iLSENumber + iIndexVariable] = j; iIndexVariable++; lseDemandData[j][5] = rightPrice; lseDemandData[j][4] = power; } } } } double HighestLSEDemandPrice = lseAggregateDemandDataPoints[0][1]; double HighestLSEDemandPower = lseAggregateDemandDataPoints[0][0]; double highestPrice = (HighestGenOfferPrice > HighestLSEDemandPrice) ? HighestGenOfferPrice : HighestLSEDemandPrice; highestPrice += 50; this.chartTitle = "True Total Supply and Demand Curves at Hour " + iDayHour; String xLabel = "Power (MWs)"; this.dataset = new XYSeriesCollection(); XYSeries series = new XYSeries("Supply"); ArrayList genTipList = new ArrayList(); String tipString = ""; leftPrice = genAggregateOfferDataPoints[0][1]; double leftPower = genAggregateOfferDataPoints[0][0]; series.add(leftPower, leftPrice); tipString = String.format("Power=%1$.2f Price=%2$.2f", leftPower, leftPrice); genTipList.add(new String(tipString)); double rightPrice = 0; double rightPower = 0; for (int i = 0; i < ((2 * iGenNumber) - 1); i++) { rightPrice = genAggregateOfferDataPoints[i][3]; rightPower = genAggregateOfferDataPoints[i][2]; series.add(rightPower, rightPrice); // For tip display tipString = String.format("Power=%1$.2f Price=%2$.2f", rightPower, rightPrice); String tempFixed = " FixedGen: "; String tempVariable = " Marginal GenCos: "; String temp; boolean bFixed = false; boolean bVariable = false; for (int j = 0; j < (2 * iGenNumber); j++) { if ((j < iGenNumber) && (genAggregateOfferCommit[i][j] != -1)) { bFixed = true; tempFixed += genData[genAggregateOfferCommit[i][j]][0] + " "; } if ((j >= iGenNumber) && (genAggregateOfferCommit[i][j] != -1)) { bVariable = true; tempVariable += genData[genAggregateOfferCommit[i][j]][0] + " "; } } if (bFixed) { tipString += tempFixed; } if (bVariable) { tipString += tempVariable; } genTipList.add(new String(tipString)); } // last infinity part series.add(rightPower, highestPrice); tipString = String.format("Power=%1$.2f Price=%2$.2f", rightPower, highestPrice); genTipList.add(new String(tipString)); this.dataset.addSeries(series); series = new XYSeries("Demand"); ArrayList LSETipList = new ArrayList(); //first infinity part series.add(HighestLSEDemandPower, highestPrice); tipString = String.format("Power=%1$.2f Price=%2$.2f", HighestLSEDemandPower, highestPrice); LSETipList.add(new String(tipString)); //second point leftPrice = lseAggregateDemandDataPoints[0][1]; leftPower = lseAggregateDemandDataPoints[0][0]; series.add(leftPower, leftPrice); tipString = String.format("Power=%1$.2f Price=%2$.2f", leftPower, leftPrice); LSETipList.add(new String(tipString)); for (int i = 0; i < ((2 * iLSENumber) - 1); i++) { rightPrice = lseAggregateDemandDataPoints[i][3]; rightPower = lseAggregateDemandDataPoints[i][2]; series.add(rightPower, rightPrice); // For tip display tipString = String.format("Power=%1$.2f Price=%2$.2f", rightPower, rightPrice); String tempFixed = " MaxPS LSE: "; String tempVariable = " VariablePS LSE: "; String temp; boolean bFixed = false; boolean bVariable = false; for (int j = 0; j < (2 * iLSENumber); j++) { if ((j < iLSENumber) && (lseAggregateDemandCommit[i][j] != -1)) { bFixed = true; tempFixed += lseData[lseAggregateDemandCommit[i][j]][0] + " "; } if ((j >= iLSENumber) && (lseAggregateDemandCommit[i][j] != -1)) { bVariable = true; tempVariable += lseData[lseAggregateDemandCommit[i][j]][0] + " "; } } if (bFixed) { tipString += tempFixed; } if (bVariable) { tipString += tempVariable; } LSETipList.add(new String(tipString)); } // last infinity part series.add(rightPower, 0.0); tipString = String.format("Power=%1$.2f Price=%2$.2f", rightPower, 0.0); LSETipList.add(new String(tipString)); this.dataset.addSeries(series); // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title xLabel, // x axis label "Price ($/MWh)", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); CustomXYToolTipGenerator customTip = new CustomXYToolTipGenerator(); customTip.addToolTipSeries(genTipList); customTip.addToolTipSeries(LSETipList); renderer.setToolTipGenerator(customTip); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawAggreagtedSupplyAndDemandData(String outputTimeTypeSelect, int iStartTime, int iEndTime, int iDayHour, int[] selectIndex) { ArrayList genAgentSupplyOfferByDay = this.amesFrame.getAMESMarket().getGenAgentSupplyOfferByDay(); double[][] genOffer = (double[][]) genAgentSupplyOfferByDay.get(iStartTime - 2); Object[][] genData = this.amesFrame.getGeneratorData(); int iGenNumber = genData.length; double[][] genOfferData = new double[iGenNumber][8]; // a, b, minCap, maxCap, 1/b, a/b, currentPower, currentPrice double[][] offerPrices = new double[iGenNumber * 2][2]; // price, index for (int i = 0; i < iGenNumber; i++) { genOfferData[i][0] = genOffer[i][0]; genOfferData[i][1] = genOffer[i][1]; genOfferData[i][2] = genOffer[i][2]; genOfferData[i][3] = genOffer[i][3]; genOfferData[i][4] = 1.0 / genOfferData[i][1]; genOfferData[i][5] = genOfferData[i][0] / genOfferData[i][1]; offerPrices[2 * i][0] = genOfferData[i][0] + (2 * genOfferData[i][1] * genOfferData[i][2]); offerPrices[2 * i][1] = 2 * i; offerPrices[(2 * i) + 1][0] = genOfferData[i][0] + (2 * genOfferData[i][1] * genOfferData[i][3]); offerPrices[(2 * i) + 1][1] = (2 * i) + 1; genOfferData[i][6] = genOfferData[i][2]; genOfferData[i][7] = offerPrices[2 * i][0]; } // sort the price of each generator double dTemp = 0; double iTemp = 0; for (int i = 0; i < (2 * iGenNumber); i++) { for (int j = i + 1; j < (2 * iGenNumber); j++) { if (offerPrices[i][0] > offerPrices[j][0]) { dTemp = offerPrices[i][0]; iTemp = offerPrices[i][1]; offerPrices[i][0] = offerPrices[j][0]; offerPrices[i][1] = offerPrices[j][1]; offerPrices[j][0] = dTemp; offerPrices[j][1] = iTemp; } } } double[][] genAggregateOfferDataPoints = new double[(iGenNumber * 2) - 1][4]; // leftPoint(power, price), rightPoint(power, price) int[][] genAggregateOfferCommit = new int[(iGenNumber * 2) - 1][iGenNumber * 2]; // in the first iGenNumber of each row is the index of gen whose output is fixed // in the second iGenNumber of each row is the index of gen whose output is variable // otherwise -1 for (int i = 0; i < ((2 * iGenNumber) - 1); i++) { for (int j = 0; j < (2 * iGenNumber); j++) { genAggregateOfferCommit[i][j] = -1; } } double leftPrice = offerPrices[0][0]; for (int i = 0; i < iGenNumber; i++) { if (leftPrice >= genOfferData[i][7]) { genAggregateOfferDataPoints[0][0] += genOfferData[i][6]; } } for (int i = 0; i < ((2 * iGenNumber) - 1); i++) { genAggregateOfferDataPoints[i][1] = offerPrices[i][0]; genAggregateOfferDataPoints[i][3] = offerPrices[i + 1][0]; if (i > 0) { genAggregateOfferDataPoints[i][0] = genAggregateOfferDataPoints[i - 1][2]; } genAggregateOfferDataPoints[i][2] = genAggregateOfferDataPoints[i][0]; int iIndexFixed = 0; int iIndexVariable = 0; double rightPrice = offerPrices[i + 1][0]; for (int j = 0; j < iGenNumber; j++) { if (rightPrice > genOfferData[j][7]) { if (Math.abs(genOfferData[j][6] - genOfferData[j][3]) < 0.000001) { // already at maxCap genAggregateOfferCommit[i][iIndexFixed++] = j; } else { double power = (rightPrice - genOfferData[j][0]) / (2 * genOfferData[j][1]); genAggregateOfferDataPoints[i][2] += power - genOfferData[j][6]; genAggregateOfferCommit[i][iGenNumber + iIndexVariable] = j; iIndexVariable++; genOfferData[j][7] = rightPrice; genOfferData[j][6] = power; } } } } double HighestGenOfferPrice = genAggregateOfferDataPoints[(iGenNumber * 2) - 2][3]; double HighestGenOfferPower = genAggregateOfferDataPoints[(iGenNumber * 2) - 2][2]; // Demand Object[][][] lsePriceSensitiveData = this.amesFrame.getLSEPriceSensitiveDemandData(); Object[][] lseHybridData = this.amesFrame.getLSEHybridDemandData(); Object[][] lseData = this.amesFrame.getLSEData(); int iLSENumber = lsePriceSensitiveData.length; double[][] lseDemandData = new double[iLSENumber][6]; // c, d, slMax, fixed demand, currentPower, currentPrice double[][] lsePrices = new double[iLSENumber * 2][2]; // price, index int hourlyLoadHybridFlagByLSE = 0; double priceCap = 1000.0; for (int i = 0; i < iLSENumber; i++) { hourlyLoadHybridFlagByLSE = Integer.parseInt(lseHybridData[i][iDayHour + 3].toString()); if ((hourlyLoadHybridFlagByLSE & 2) == 2) { double c = Support.parseDouble(lsePriceSensitiveData[i][iDayHour][4].toString()); double d = Support.parseDouble(lsePriceSensitiveData[i][iDayHour][5].toString()); double slMax = Support.parseDouble(lsePriceSensitiveData[i][iDayHour][6].toString()); lseDemandData[i][0] = c; lseDemandData[i][1] = d; lseDemandData[i][2] = slMax; lseDemandData[i][4] = 0.0; lseDemandData[i][5] = c; lsePrices[2 * i][0] = c; lsePrices[2 * i][1] = 2 * i; lsePrices[(2 * i) + 1][0] = c - (2 * d * slMax); lsePrices[(2 * i) + 1][1] = (2 * i) + 1; } else { lseDemandData[i][0] = 0.0; lseDemandData[i][1] = 0.0; lseDemandData[i][2] = 0.0; lseDemandData[i][4] = 0.0; lseDemandData[i][5] = priceCap; lsePrices[2 * i][0] = priceCap; lsePrices[2 * i][1] = 2 * i; lsePrices[(2 * i) + 1][0] = priceCap; lsePrices[(2 * i) + 1][1] = (2 * i) + 1; } if ((hourlyLoadHybridFlagByLSE & 1) == 1) { // fixed demand lseDemandData[i][3] = Support.parseDouble(lseData[i][iDayHour + 3].toString()); } } // sort the price of each lse for (int i = 0; i < (2 * iLSENumber); i++) { for (int j = i + 1; j < (2 * iLSENumber); j++) { if (lsePrices[i][0] < lsePrices[j][0]) { dTemp = lsePrices[i][0]; iTemp = lsePrices[i][1]; lsePrices[i][0] = lsePrices[j][0]; lsePrices[i][1] = lsePrices[j][1]; lsePrices[j][0] = dTemp; lsePrices[j][1] = iTemp; } } } double[][] lseAggregateDemandDataPoints = new double[(iLSENumber * 2) - 1][4]; // leftPoint(power, price), rightPoint(power, price) int[][] lseAggregateDemandCommit = new int[(iLSENumber * 2) - 1][iLSENumber * 2]; // in the first iLSENumber of each row is the index of LSE whose commit is fixed // in the second iLSENumber of each row is the index of LSE whose commit is variable // otherwise -1 for (int i = 0; i < ((2 * iLSENumber) - 1); i++) { for (int j = 0; j < (2 * iLSENumber); j++) { lseAggregateDemandCommit[i][j] = -1; } } leftPrice = lsePrices[0][0]; for (int i = 0; i < iLSENumber; i++) { lseAggregateDemandDataPoints[0][0] += lseDemandData[i][3]; if (leftPrice <= lseDemandData[i][5]) { lseAggregateDemandDataPoints[0][0] += lseDemandData[i][4]; } } for (int i = 0; i < ((2 * iLSENumber) - 1); i++) { lseAggregateDemandDataPoints[i][1] = lsePrices[i][0]; lseAggregateDemandDataPoints[i][3] = lsePrices[i + 1][0]; if (i > 0) { lseAggregateDemandDataPoints[i][0] = lseAggregateDemandDataPoints[i - 1][2]; } lseAggregateDemandDataPoints[i][2] = lseAggregateDemandDataPoints[i][0]; int iIndexFixed = 0; int iIndexVariable = 0; double rightPrice = lsePrices[i + 1][0]; for (int j = 0; j < iLSENumber; j++) { if (rightPrice < lseDemandData[j][5]) { if (Math.abs(lseDemandData[j][4] - lseDemandData[j][2]) < 0.000001) { // already at slMax lseAggregateDemandCommit[i][iIndexFixed++] = j; } else { double power = (lseDemandData[j][0] - rightPrice) / (2 * lseDemandData[j][1]); lseAggregateDemandDataPoints[i][2] += power - lseDemandData[j][4]; lseAggregateDemandCommit[i][iLSENumber + iIndexVariable] = j; iIndexVariable++; lseDemandData[j][5] = rightPrice; lseDemandData[j][4] = power; } } } } double HighestLSEDemandPrice = lseAggregateDemandDataPoints[0][1]; double HighestLSEDemandPower = lseAggregateDemandDataPoints[0][0]; double highestPrice = (HighestGenOfferPrice > HighestLSEDemandPrice) ? HighestGenOfferPrice : HighestLSEDemandPrice; highestPrice += 50; this.chartTitle = "Reported Total Supply and Demand Curves at Day " + iStartTime + " Hour " + iDayHour; String xLabel = "Power (MWs)"; this.dataset = new XYSeriesCollection(); XYSeries series = new XYSeries("Supply"); ArrayList genTipList = new ArrayList(); String tipString = ""; leftPrice = genAggregateOfferDataPoints[0][1]; double leftPower = genAggregateOfferDataPoints[0][0]; series.add(leftPower, leftPrice); tipString = String.format("Power=%1$.2f Price=%2$.2f", leftPower, leftPrice); genTipList.add(new String(tipString)); double rightPrice = 0; double rightPower = 0; for (int i = 0; i < ((2 * iGenNumber) - 1); i++) { rightPrice = genAggregateOfferDataPoints[i][3]; rightPower = genAggregateOfferDataPoints[i][2]; series.add(rightPower, rightPrice); // For tip display tipString = String.format("Power=%1$.2f Price=%2$.2f", rightPower, rightPrice); String tempFixed = " FixedGen: "; String tempVariable = " Marginal GenCos: "; String temp; boolean bFixed = false; boolean bVariable = false; for (int j = 0; j < (2 * iGenNumber); j++) { if ((j < iGenNumber) && (genAggregateOfferCommit[i][j] != -1)) { bFixed = true; tempFixed += genData[genAggregateOfferCommit[i][j]][0] + " "; } if ((j >= iGenNumber) && (genAggregateOfferCommit[i][j] != -1)) { bVariable = true; tempVariable += genData[genAggregateOfferCommit[i][j]][0] + " "; } } if (bFixed) { tipString += tempFixed; } if (bVariable) { tipString += tempVariable; } genTipList.add(new String(tipString)); } // last infinity part series.add(rightPower, highestPrice); tipString = String.format("Power=%1$.2f Price=%2$.2f", rightPower, highestPrice); genTipList.add(new String(tipString)); this.dataset.addSeries(series); series = new XYSeries("Demand"); ArrayList LSETipList = new ArrayList(); //first infinity part series.add(HighestLSEDemandPower, highestPrice); tipString = String.format("Power=%1$.2f Price=%2$.2f", HighestLSEDemandPower, highestPrice); LSETipList.add(new String(tipString)); //second point leftPrice = lseAggregateDemandDataPoints[0][1]; leftPower = lseAggregateDemandDataPoints[0][0]; series.add(leftPower, leftPrice); tipString = String.format("Power=%1$.2f Price=%2$.2f", leftPower, leftPrice); LSETipList.add(new String(tipString)); for (int i = 0; i < ((2 * iLSENumber) - 1); i++) { rightPrice = lseAggregateDemandDataPoints[i][3]; rightPower = lseAggregateDemandDataPoints[i][2]; series.add(rightPower, rightPrice); // For tip display tipString = String.format("Power=%1$.2f Price=%2$.2f", rightPower, rightPrice); String tempFixed = " MaxPS LSE: "; String tempVariable = " VariablePS LSE: "; String temp; boolean bFixed = false; boolean bVariable = false; for (int j = 0; j < (2 * iLSENumber); j++) { if ((j < iLSENumber) && (lseAggregateDemandCommit[i][j] != -1)) { bFixed = true; tempFixed += lseData[lseAggregateDemandCommit[i][j]][0] + " "; } if ((j >= iLSENumber) && (lseAggregateDemandCommit[i][j] != -1)) { bVariable = true; tempVariable += lseData[lseAggregateDemandCommit[i][j]][0] + " "; } } if (bFixed) { tipString += tempFixed; } if (bVariable) { tipString += tempVariable; } LSETipList.add(new String(tipString)); } // last infinity part series.add(rightPower, 0.0); tipString = String.format("Power=%1$.2f Price=%2$.2f", rightPower, 0.0); LSETipList.add(new String(tipString)); this.dataset.addSeries(series); // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title xLabel, // x axis label "Price ($/MWh)", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); CustomXYToolTipGenerator customTip = new CustomXYToolTipGenerator(); customTip.addToolTipSeries(genTipList); customTip.addToolTipSeries(LSETipList); renderer.setToolTipGenerator(customTip); //renderer.setSeriesStroke(0, new BasicStroke(3.0f)); //renderer.setSeriesStroke(1, new BasicStroke(3.0f)); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); //xAxis.setLabelFont(font); //xAxis.setTickLabelFont(font); //NumberAxis yAxis = (NumberAxis) plot.getRangeAxis(); //yAxis.setLabelFont(font); //yAxis.setTickLabelFont(font); this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawGeneratorSupplyOfferData(String outputTimeTypeSelect, int iStartTime, int iEndTime, int[] selectIndex) { String[] names = { "GenCo Name", "Day Index", "aR ($/MWh)", "bR ($/MW2h)", "CapRL (MW)", "CapRU (MW)", }; ArrayList genAgentSupplyOfferByDay = this.amesFrame.getAMESMarket().getGenAgentSupplyOfferByDay(); Object[][] genData = this.amesFrame.getGeneratorData(); int iGenNumber = genData.length; String xLabel = "Power (MWs)"; this.dataset = new XYSeriesCollection(); if (selectIndex.length < 1) { JOptionPane.showMessageDialog(this, "No GenCo is selected!", "Error Message", JOptionPane.ERROR_MESSAGE); return; } double[][] genOffer = (double[][]) genAgentSupplyOfferByDay.get(iStartTime - 1); int genIndex = selectIndex[0]; this.chartTitle = genData[genIndex][0] + " Supply Offer for Day " + iStartTime; XYSeries series = new XYSeries("Reported"); double dStart = genOffer[genIndex][0] + (2.0 * genOffer[genIndex][1] * genOffer[genIndex][2]); double dEnd = genOffer[genIndex][0] + (2.0 * genOffer[genIndex][1] * genOffer[genIndex][3]); series.add(genOffer[genIndex][2], dStart); series.add(genOffer[genIndex][3], dEnd); this.dataset.addSeries(series); series = new XYSeries("True"); double da = Support.parseDouble(genData[genIndex][4].toString()); double db = Support.parseDouble(genData[genIndex][5].toString()); double dMinCap = Support.parseDouble(genData[genIndex][6].toString()); double dMaxCap = Support.parseDouble(genData[genIndex][7].toString()); dStart = da + (2.0 * db * dMinCap); dEnd = da + (2.0 * db * dMaxCap); series.add(dMinCap, dStart); series.add(dMaxCap, dEnd); this.dataset.addSeries(series); // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title xLabel, // x axis label "Price ($/MWh)", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); renderer.setToolTipGenerator(generator); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawGeneratorCommitmentData(String outputTimeTypeSelect, int iStartTime, int iEndTime, int iDayHour, int[] selectIndex) { String[] names = { " GenCo Name", "Day Index", " Hour", " Power (MW)", "CapRL (MW)", "CapRU (MW)" }; this.chartTitle = "GenCo Commitments"; String xLabel = ""; iStartTime = iStartTime - 1; iEndTime = iEndTime - 1; ArrayList genAgentCommitmentByDay = this.amesFrame.getAMESMarket().getGenAgentCommitmentByDay(); ArrayList hasSolutionByDay = this.amesFrame.getAMESMarket().getHasSolutionByDay(); int[] hasSolutions; this.dataset = new XYSeriesCollection(); Object[][] genData = this.amesFrame.getGeneratorData(); int iGenNumber = genData.length; if ((selectIndex.length < 1) || (selectIndex[0] == 0)) { if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run (Selected Hour)")) { int iDayNumber = genAgentCommitmentByDay.size(); double[][] genCommitment; this.chartTitle = this.chartTitle + "\n " + "for Entire Run (At Hour " + iDayHour + ":00)"; xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; for (int j = 0; j < iGenNumber; j++) { XYSeries series = new XYSeries((String) genData[j][0]); for (int iDay = 0; iDay < iDayNumber; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); genCommitment = (double[][]) genAgentCommitmentByDay.get(iDay); series.add(iDay + 2, (Math.round(genCommitment[iDayHour][j] * 1000)) / 1000.0); if (hasSolutions[iDayHour] == 0) { noSolutionSeries.add(iDay + 2, 0.0); bNoSolution = true; } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day (Selected Hour)")) { int iDayNumber = (iEndTime - iStartTime) + 1; double[][] genCommitment; this.chartTitle = this.chartTitle + "\n " + "From Day " + (iStartTime + 1) + " to Day " + (iEndTime + 1) + " (At Hour " + iDayHour + ":00)"; xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; for (int j = 0; j < iGenNumber; j++) { XYSeries series = new XYSeries((String) genData[j][0]); for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); genCommitment = (double[][]) genAgentCommitmentByDay.get(iDay); series.add(iDay + 2, (Math.round(genCommitment[iDayHour][j] * 1000)) / 1000.0); if (hasSolutions[iDayHour] == 0) { noSolutionSeries.add(iDay + 2, 0.0); bNoSolution = true; } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } } else if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run (All Hours)")) { int iDayNumber = genAgentCommitmentByDay.size(); double[][] genCommitment; this.chartTitle = this.chartTitle + "\n " + "for Entire Run"; xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; for (int j = 0; j < iGenNumber; j++) { XYSeries series = new XYSeries((String) genData[j][0]); for (int iDay = 0; iDay < iDayNumber; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); genCommitment = (double[][]) genAgentCommitmentByDay.get(iDay); for (int i = 0; i < 24; i++) { series.add(iDay + 1 + (i / 24.0), (Math.round(genCommitment[i][j] * 1000)) / 1000.0); if (hasSolutions[i] == 0) { noSolutionSeries.add(iDay + 1 + (i / 24.0), 0.0); bNoSolution = true; } } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day (All Hours)")) { int iDayNumber = (iEndTime - iStartTime) + 1; double[][] genCommitment; this.chartTitle = this.chartTitle + "\n " + "From Day " + (iStartTime + 1) + " to Day " + (iEndTime + 1) + " (All Hours)"; xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; for (int j = 0; j < iGenNumber; j++) { XYSeries series = new XYSeries((String) genData[j][0]); for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { genCommitment = (double[][]) genAgentCommitmentByDay.get(iDay); hasSolutions = (int[]) hasSolutionByDay.get(iDay); for (int i = 0; i < 24; i++) { series.add(iDay + 1 + (i / 24.0), (Math.round(genCommitment[i][j] * 1000)) / 1000.0); if (hasSolutions[i] == 0) { noSolutionSeries.add(iDay + 1 + (i / 24.0), 0.0); bNoSolution = true; } } } this.dataset.addSeries(series); if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } } } } else { int iDataNumber = selectIndex.length; int iField = names.length; if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run (Selected Hour)")) { int iDayNumber = genAgentCommitmentByDay.size(); double[][] genCommitment; this.chartTitle = this.chartTitle + "\n " + "for Entire Run (At Hour " + iDayHour + ":00)"; xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; for (int j = 0; j < iDataNumber; j++) { XYSeries series = new XYSeries((String) genData[selectIndex[j] - 1][0]); for (int iDay = 0; iDay < iDayNumber; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); genCommitment = (double[][]) genAgentCommitmentByDay.get(iDay); series.add(iDay + 1, (Math.round(genCommitment[iDayHour][selectIndex[j] - 1] * 1000)) / 1000.0); if (hasSolutions[iDayHour] == 0) { noSolutionSeries.add(iDay + 1, 0.0); bNoSolution = true; } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day (Selected Hour)")) { int iDayNumber = (iEndTime - iStartTime) + 1; double[][] genCommitment; this.chartTitle = this.chartTitle + "\n " + "From Day " + (iStartTime + 1) + " to Day " + (iEndTime + 1) + " (At Hour " + iDayHour + ":00)"; xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; for (int j = 0; j < iDataNumber; j++) { XYSeries series = new XYSeries((String) genData[selectIndex[j] - 1][0]); for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); genCommitment = (double[][]) genAgentCommitmentByDay.get(iDay); series.add(iDay + 2, (Math.round(genCommitment[iDayHour][selectIndex[j] - 1] * 1000)) / 1000.0); if (hasSolutions[iDayHour] == 0) { noSolutionSeries.add(iDay + 2, 0.0); bNoSolution = true; } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } } else if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run (All Hours)")) { int iDayNumber = genAgentCommitmentByDay.size(); double[][] genCommitment; this.chartTitle = this.chartTitle + "\n " + "for Entire Run"; xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; for (int j = 0; j < iDataNumber; j++) { XYSeries series = new XYSeries((String) genData[selectIndex[j] - 1][0]); for (int iDay = 0; iDay < iDayNumber; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); genCommitment = (double[][]) genAgentCommitmentByDay.get(iDay); for (int i = 0; i < 24; i++) { series.add(iDay + 1 + (i / 24.0), (Math.round(genCommitment[i][selectIndex[j] - 1] * 1000)) / 1000.0); if (hasSolutions[i] == 0) { noSolutionSeries.add(iDay + 1 + (i / 24.0), 0.0); bNoSolution = true; } } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day (All Hours)")) { int iDayNumber = (iEndTime - iStartTime) + 1; double[][] genCommitment; this.chartTitle = this.chartTitle + "\n " + "From Day " + (iStartTime + 1) + " to Day " + (iEndTime + 1) + " (All Hours)"; xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; for (int j = 0; j < iDataNumber; j++) { XYSeries series = new XYSeries((String) genData[selectIndex[j] - 1][0]); for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); genCommitment = (double[][]) genAgentCommitmentByDay.get(iDay); for (int i = 0; i < 24; i++) { series.add(iDay + 1 + (i / 24.0), (Math.round(genCommitment[i][selectIndex[j] - 1] * 1000)) / 1000.0); if (hasSolutions[i] == 0) { noSolutionSeries.add(iDay + 1 + (i / 24.0), 0.0); bNoSolution = true; } } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } } } // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title xLabel, // x axis label "Power (MWs)", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); renderer.setToolTipGenerator(generator); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawGeneratorProfitAndNetEarningsData(String outputTimeTypeSelect, int iStartTime, int iEndTime, int[] selectIndex, boolean bProfit) { if (bProfit) { this.chartTitle = "GenCo Daily Profits"; } else { this.chartTitle = "GenCo Daily Net Earnings"; } ArrayList genAgentProfitAndNetGainByDay = this.amesFrame.getAMESMarket().getGenAgentProfitAndNetGainByDay(); boolean draw3DChart = false; this.dataset = new XYSeriesCollection(); DefaultCategoryDataset dataset3D = new DefaultCategoryDataset(); Object[][] genData = this.amesFrame.getGeneratorData(); int iGenNumber = genData.length; if ((selectIndex.length < 1) || (selectIndex[0] == 0)) { if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run")) { int iDayNumber = genAgentProfitAndNetGainByDay.size(); double[][] genProfit; this.chartTitle = this.chartTitle + "\n " + "for Entire Run"; for (int i = 0; i < iGenNumber; i++) { String genName = (String) genData[i][0]; XYSeries series1; series1 = new XYSeries(genName); for (int iDay = 0; iDay < iDayNumber; iDay++) { genProfit = (double[][]) genAgentProfitAndNetGainByDay.get(iDay); if (bProfit) { series1.add(iDay + 1, (Math.round(genProfit[i][0] * 1000)) / 1000.0); } else { series1.add(iDay + 1, (Math.round(genProfit[i][1] * 1000)) / 1000.0); } } this.dataset.addSeries(series1); } } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day")) { int iDayNumber = (iEndTime - iStartTime) + 1; double[][] genProfit; this.chartTitle = this.chartTitle + "\n " + "From Day " + iStartTime + " to Day " + iEndTime; for (int i = 0; i < iGenNumber; i++) { String genName = (String) genData[i][0]; XYSeries series1; series1 = new XYSeries(genName); for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { genProfit = (double[][]) genAgentProfitAndNetGainByDay.get(iDay); if (bProfit) { series1.add(iDay + 1, (Math.round(genProfit[i][0] * 1000)) / 1000.0); } else { series1.add(iDay + 1, (Math.round(genProfit[i][1] * 1000)) / 1000.0); } } this.dataset.addSeries(series1); } } } else { int iDataNumber = selectIndex.length; if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run")) { int iDayNumber = genAgentProfitAndNetGainByDay.size(); double[][] genProfit; this.chartTitle = this.chartTitle + "\n " + "for Entire Run"; for (int i = 0; i < iDataNumber; i++) { String genName = (String) genData[selectIndex[i] - 1][0]; XYSeries series1; series1 = new XYSeries(genName); for (int iDay = 0; iDay < iDayNumber; iDay++) { genProfit = (double[][]) genAgentProfitAndNetGainByDay.get(iDay); if (bProfit) { series1.add(iDay + 1, (Math.round(genProfit[selectIndex[i] - 1][0] * 1000)) / 1000.0); } else { series1.add(iDay + 1, (Math.round(genProfit[selectIndex[i] - 1][1] * 1000)) / 1000.0); } } this.dataset.addSeries(series1); } } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day")) { int iDayNumber = (iEndTime - iStartTime) + 1; double[][] genProfit; this.chartTitle = this.chartTitle + "\n " + "From Day " + iStartTime + " to Day " + iEndTime; for (int i = 0; i < iDataNumber; i++) { String genName = (String) genData[selectIndex[i] - 1][0]; XYSeries series1; series1 = new XYSeries(genName); for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { genProfit = (double[][]) genAgentProfitAndNetGainByDay.get(iDay); if (bProfit) { series1.add(iDay + 1, (Math.round(genProfit[selectIndex[i] - 1][0] * 1000)) / 1000.0); } else { series1.add(iDay + 1, (Math.round(genProfit[selectIndex[i] - 1][1] * 1000)) / 1000.0); } } this.dataset.addSeries(series1); } } } if (draw3DChart) { this.chart = ChartFactory.createBarChart3D(this.chartTitle, // chart title "Value Category", // domain axis label "Value ($/D)", // range axis label dataset3D, // data PlotOrientation.VERTICAL, // orientation true, // include legend true, // tooltips false // urls ); final CategoryPlot plot = this.chart.getCategoryPlot(); final CategoryAxis axis = plot.getDomainAxis(); axis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 8.0)); final CategoryItemRenderer renderer = plot.getRenderer(); renderer.setItemLabelsVisible(true); final BarRenderer r = (BarRenderer) renderer; r.setMaximumBarWidth(0.05); } else { // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title "Day", // x axis label "Money ($/D)", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); renderer.setToolTipGenerator(generator); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); } this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawLSESurplusData(String outputTimeTypeSelect, int iStartTime, int iEndTime, int[] selectIndex) { String[] names = { "LSE Name", "Day Index", "Surplus ($/H)" }; this.chartTitle = "LSE Daily Net Earnings"; ArrayList lseAgentSurplusByDay = this.amesFrame.getAMESMarket().getLSEAgentSurplusByDay(); boolean draw3DChart = false; this.dataset = new XYSeriesCollection(); DefaultCategoryDataset dataset3D = new DefaultCategoryDataset(); Object[][] lseHybridData = this.amesFrame.getLSEHybridDemandData(); int iLSENumber = lseHybridData.length; if ((selectIndex.length < 1) || (selectIndex[0] == 0)) { if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run")) { int iDayNumber = lseAgentSurplusByDay.size(); double[][] lseSurplus; this.chartTitle = this.chartTitle + "\n " + "for Entire Run"; for (int i = 0; i < iLSENumber; i++) { String lseName = (String) lseHybridData[i][0]; XYSeries series1 = new XYSeries(lseName + " Surplus"); for (int iDay = 0; iDay < iDayNumber; iDay++) { lseSurplus = (double[][]) lseAgentSurplusByDay.get(iDay); series1.add(iDay + 1, (Math.round(lseSurplus[i][0] * 1000)) / 1000.0); } this.dataset.addSeries(series1); } } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day")) { int iDayNumber = (iEndTime - iStartTime) + 1; double[][] lseSurplus; this.chartTitle = this.chartTitle + "\n " + "From Day " + iStartTime + " to Day " + iEndTime; for (int i = 0; i < iLSENumber; i++) { String lseName = (String) lseHybridData[i][0]; XYSeries series1 = new XYSeries(lseName + " Surplus"); for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { lseSurplus = (double[][]) lseAgentSurplusByDay.get(iDay); series1.add(iDay + 1, (Math.round(lseSurplus[i][0] * 1000)) / 1000.0); } this.dataset.addSeries(series1); } } } else { int iDataNumber = selectIndex.length; int iField = names.length; if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run")) { int iDayNumber = lseAgentSurplusByDay.size(); double[][] lseSurplus; this.chartTitle = this.chartTitle + "\n " + "for Entire Run"; for (int i = 0; i < iDataNumber; i++) { String lseName = (String) lseHybridData[selectIndex[i] - 1][0]; XYSeries series1 = new XYSeries(lseName + " Surplus"); for (int iDay = 0; iDay < iDayNumber; iDay++) { lseSurplus = (double[][]) lseAgentSurplusByDay.get(iDay); series1.add(iDay + 1, (Math.round(lseSurplus[selectIndex[i] - 1][0] * 1000)) / 1000.0); } this.dataset.addSeries(series1); } } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day")) { int iDayNumber = (iEndTime - iStartTime) + 1; double[][] lseSurplus; this.chartTitle = this.chartTitle + "\n " + "From Day " + iStartTime + " to Day " + iEndTime; for (int i = 0; i < iDataNumber; i++) { String lseName = (String) lseHybridData[selectIndex[i] - 1][0]; XYSeries series1 = new XYSeries(lseName + " Surplus"); for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { lseSurplus = (double[][]) lseAgentSurplusByDay.get(iDay); series1.add(iDay + 1, (Math.round(lseSurplus[selectIndex[i] - 1][0] * 1000)) / 1000.0); } this.dataset.addSeries(series1); } } } if (draw3DChart) { this.chart = ChartFactory.createBarChart3D(this.chartTitle, // chart title "Value Category", // domain axis label "Value", // range axis label dataset3D, // data PlotOrientation.VERTICAL, // orientation true, // include legend true, // tooltips false // urls ); final CategoryPlot plot = this.chart.getCategoryPlot(); final CategoryAxis axis = plot.getDomainAxis(); axis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 8.0)); final CategoryItemRenderer renderer = plot.getRenderer(); renderer.setItemLabelsVisible(true); final BarRenderer r = (BarRenderer) renderer; r.setMaximumBarWidth(0.05); } else { // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title "Day", // x axis label "Value", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); renderer.setToolTipGenerator(generator); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); } this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawLSEPriceSensitiveDemandData(String outputTimeTypeSelect, int iStartTime, int iEndTime, int iDayHour, int[] selectIndex) { String[] names = { "LSE Name", "Day Index", "Hour", "c ($/MWh)", "d ($/MW2h)", "SLMax (MW)", "Price-Sensitive Demand (MW)" }; Object[][][] lsePriceSensitiveData = this.amesFrame.getLSEPriceSensitiveDemandData(); Object[][] lseHybridData = this.amesFrame.getLSEHybridDemandData(); int iLSENumber = lsePriceSensitiveData.length; ArrayList LMPByDay = this.amesFrame.getAMESMarket().getLMPByDay(); ArrayList priceSensitiveByDay = this.amesFrame.getAMESMarket().getLSEAgenPriceSensitiveDemandByDay(); this.chartTitle = "LSE Price-Sensitive Demand Function and Cleared Point"; String xLabel = "Power (MWs)"; this.dataset = new XYSeriesCollection(); if (selectIndex.length < 1) { JOptionPane.showMessageDialog(this, "No LSE is selected!", "Error Message", JOptionPane.ERROR_MESSAGE); return; } double[][] lsePS = (double[][]) priceSensitiveByDay.get(iStartTime - 2); double[][] lmp = (double[][]) LMPByDay.get(iStartTime - 2); int lseIndex = selectIndex[0]; int lseAtBus = Integer.parseInt(lseHybridData[lseIndex][2].toString()); double busLMP = lmp[iDayHour][lseAtBus - 1]; this.chartTitle = this.chartTitle + "\n " + lsePriceSensitiveData[lseIndex][0][0] + " for Day " + iStartTime + " ( At Hour " + iDayHour + ":00)"; XYSeries series = new XYSeries("Cleared Point"); int psLoadIndex = 0; // Get the psLoadIndex for (int k = 0; k < selectIndex[0]; k++) { int hourlyFlag = Integer.parseInt(lseHybridData[k][iDayHour + 3].toString()); if ((hourlyFlag & 2) == 2) { psLoadIndex++; } } double dStart = 0; double dEnd = 0; int hourlyLoadHybridFlagByLSE = Integer.parseInt(lseHybridData[selectIndex[0]][iDayHour + 3].toString()); if ((hourlyLoadHybridFlagByLSE & 2) == 2) { dStart = lsePS[iDayHour][psLoadIndex]; } double c = Support.parseDouble(lsePriceSensitiveData[lseIndex][iDayHour][4].toString()); double d = Support.parseDouble(lsePriceSensitiveData[lseIndex][iDayHour][5].toString()); double slMax = Support.parseDouble(lsePriceSensitiveData[lseIndex][iDayHour][6].toString()); //dEnd=c-2.0*d*dStart; series.add(dStart, busLMP); this.dataset.addSeries(series); series = new XYSeries("Price-Sensitive Demand Function"); dEnd = c - (2.0 * d * slMax); series.add(0, c); series.add(slMax, dEnd); this.dataset.addSeries(series); // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title xLabel, // x axis label "Price ($/MWh)", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); renderer.setToolTipGenerator(generator); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawBranchPowerFlowData(String outputTimeTypeSelect, int iStartTime, int iEndTime, int iDayHour, int[] selectIndex) { String[] names = { "Branch Name", "Day Index", "Hour", "Power (MW)", "MaxCap (MW)" }; this.chartTitle = "Branch Power Flows"; boolean bSubtitle = false; String subtitles = ""; String xLabel = ""; iStartTime = iStartTime - 1; iEndTime = iEndTime - 1; ArrayList branchFlowByDay = this.amesFrame.getAMESMarket().getBranchFlowByDay(); ArrayList hasSolutionByDay = this.amesFrame.getAMESMarket().getHasSolutionByDay(); int[] hasSolutions; Object[][] branchData = this.amesFrame.getBranchData(); int iBranchNumber = branchData.length; boolean draw3DChart = false; this.dataset = new XYSeriesCollection(); DefaultCategoryDataset dataset3D = new DefaultCategoryDataset(); if ((selectIndex.length < 1) || (selectIndex[0] == 0)) { if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run (Selected Hour)")) { this.chartTitle = this.chartTitle + "\n " + "For Entire Run (At Hour " + iDayHour + ":00)\n"; xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; int iDayNumber = branchFlowByDay.size(); double[][] branchFlow; for (int j = 0; j < iBranchNumber; j++) { XYSeries series = new XYSeries((String) branchData[j][0]); for (int iDay = 0; iDay < iDayNumber; iDay++) { branchFlow = (double[][]) branchFlowByDay.get(iDay); hasSolutions = (int[]) hasSolutionByDay.get(iDay); series.add(iDay + 2, (Math.round(branchFlow[iDayHour][j] * 1000)) / 1000.0); if (hasSolutions[iDayHour] == 0) { noSolutionSeries.add(iDay + 2, 0.0); bNoSolution = true; } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day (Selected Hour)")) { int iDayNumber = (iEndTime - iStartTime) + 1; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; double[][] branchFlow; for (int j = 0; j < iBranchNumber; j++) { XYSeries series = new XYSeries((String) branchData[j][0]); for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { branchFlow = (double[][]) branchFlowByDay.get(iDay); hasSolutions = (int[]) hasSolutionByDay.get(iDay); series.add(iDay + 2, (Math.round(branchFlow[iDayHour][j] * 1000)) / 1000.0); if (hasSolutions[iDayHour] == 0) { noSolutionSeries.add(iDay + 2, 0.0); bNoSolution = true; } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } this.chartTitle = this.chartTitle + "\n " + "From Day " + (iStartTime + 1) + " to Day " + (iEndTime + 1) + " (At Hour " + iDayHour + ":00)"; xLabel = "Day"; } else if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run (All Hours)")) { int iDayNumber = branchFlowByDay.size(); XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; double[][] branchFlow; for (int j = 0; j < iBranchNumber; j++) { XYSeries series = new XYSeries((String) branchData[j][0]); for (int iDay = 0; iDay < iDayNumber; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); branchFlow = (double[][]) branchFlowByDay.get(iDay); for (int i = 0; i < 24; i++) { series.add(iDay + 1 + (i / 24.0), (Math.round(branchFlow[i][j] * 1000)) / 1000.0); if (hasSolutions[i] == 0) { noSolutionSeries.add(iDay + 1 + (i / 24.0), 0.0); bNoSolution = true; } } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } this.chartTitle = this.chartTitle + "\n " + "For Entire Run (All Hours)"; xLabel = "Day"; } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day (All Hours)")) { int iDayNumber = (iEndTime - iStartTime) + 1; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; double[][] branchFlow; for (int j = 0; j < iBranchNumber; j++) { XYSeries series = new XYSeries((String) branchData[j][0]); for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); branchFlow = (double[][]) branchFlowByDay.get(iDay); for (int i = 0; i < 24; i++) { series.add(iDay + 1 + (i / 24.0), (Math.round(branchFlow[i][j] * 1000)) / 1000.0); if (hasSolutions[i] == 0) { noSolutionSeries.add(iDay + 1 + (i / 24.0), 0.0); bNoSolution = true; } } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } this.chartTitle = this.chartTitle + "\n " + "From Day " + (iStartTime + 1) + " to Day " + (iEndTime + 1) + " (All Hours)"; xLabel = "Day"; } } else { int iDataNumber = selectIndex.length; if (iDataNumber == 1) { bSubtitle = true; } int iField = names.length; if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run (Selected Hour)")) { XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; int iDayNumber = branchFlowByDay.size(); double[][] branchFlow; for (int j = 0; j < iDataNumber; j++) { XYSeries series = new XYSeries((String) branchData[selectIndex[j] - 1][0]); subtitles += branchData[selectIndex[j] - 1][0] + " Thermal Limit: " + branchData[selectIndex[j] - 1][3].toString() + "\n"; for (int iDay = 0; iDay < iDayNumber; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); branchFlow = (double[][]) branchFlowByDay.get(iDay); series.add(iDay + 2, (Math.round(branchFlow[iDayHour][selectIndex[j] - 1] * 1000)) / 1000.0); if (hasSolutions[iDayHour] == 0) { noSolutionSeries.add(iDay + 2, 0.0); bNoSolution = true; } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } this.chartTitle = this.chartTitle + "\n " + "For Entire Run (At Hour " + iDayHour + ":00)"; xLabel = "Day"; } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day (Selected Hour)")) { XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; int iDayNumber = (iEndTime - iStartTime) + 1; double[][] branchFlow; for (int j = 0; j < iDataNumber; j++) { XYSeries series = new XYSeries((String) branchData[selectIndex[j] - 1][0]); subtitles += branchData[selectIndex[j] - 1][0] + " Thermal Limit: " + branchData[selectIndex[j] - 1][3].toString() + "\n"; for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); branchFlow = (double[][]) branchFlowByDay.get(iDay); series.add(iDay + 2, (Math.round(branchFlow[iDayHour][selectIndex[j] - 1] * 1000)) / 1000.0); if (hasSolutions[iDayHour] == 0) { noSolutionSeries.add(iDay + 2, 0.0); bNoSolution = true; } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } this.chartTitle = this.chartTitle + "\n " + "From Day " + (iStartTime + 1) + " to Day " + (iEndTime + 1) + " (At Hour " + iDayHour + ":00)"; xLabel = "Day"; } else if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run (All Hours)")) { XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; int iDayNumber = branchFlowByDay.size(); double[][] branchFlow; for (int j = 0; j < iDataNumber; j++) { XYSeries series = new XYSeries((String) branchData[selectIndex[j] - 1][0]); subtitles += branchData[selectIndex[j] - 1][0] + " Thermal Limit: " + branchData[selectIndex[j] - 1][3].toString() + "\n"; for (int iDay = 0; iDay < iDayNumber; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); branchFlow = (double[][]) branchFlowByDay.get(iDay); for (int i = 0; i < 24; i++) { series.add(iDay + 1 + (i / 24.0), (Math.round(branchFlow[i][selectIndex[j] - 1] * 1000)) / 1000.0); if (hasSolutions[i] == 0) { noSolutionSeries.add(iDay + 1 + (i / 24.0), 0.0); bNoSolution = true; } } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } this.chartTitle = this.chartTitle + "\n " + "For Entire Run (All Hours)"; xLabel = "Day"; } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day (All Hours)")) { XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; int iDayNumber = (iEndTime - iStartTime) + 1; double[][] branchFlow; for (int j = 0; j < iDataNumber; j++) { XYSeries series = new XYSeries((String) branchData[selectIndex[j] - 1][0]); subtitles += branchData[selectIndex[j] - 1][0] + " Thermal Limit: " + branchData[selectIndex[j] - 1][3].toString() + "\n"; for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); branchFlow = (double[][]) branchFlowByDay.get(iDay); for (int i = 0; i < 24; i++) { series.add(iDay + 1 + (i / 24.0), (Math.round(branchFlow[i][selectIndex[j] - 1] * 1000)) / 1000.0); if (hasSolutions[i] == 0) { noSolutionSeries.add(iDay + 1 + (i / 24.0), 0.0); bNoSolution = true; } } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } this.chartTitle = this.chartTitle + "\n " + "From Day " + (iStartTime + 1) + " to Day " + (iEndTime + 1) + " (All Hours)"; xLabel = "Day"; } } // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title xLabel, // x axis label "Power (MWs)", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); if (bSubtitle) { TextTitle subTitle = new TextTitle(); subTitle.setText(subtitles); this.chart.addSubtitle(subTitle); } // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART... this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); renderer.setToolTipGenerator(generator); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void drawNodeLMPData(String outputTimeTypeSelect, int iStartTime, int iEndTime, int iDayHour, int[] selectIndex) { String[] names = { "Bus Name", "Day Index", " Hour", "LMP ($/MWh)" }; this.chartTitle = "Locational Marginal Price"; String xLabel = ""; iStartTime = iStartTime - 1; iEndTime = iEndTime - 1; ArrayList LMPByDay = this.amesFrame.getAMESMarket().getLMPByDay(); ArrayList hasSolutionByDay = this.amesFrame.getAMESMarket().getHasSolutionByDay(); int[] hasSolutions; String[] nodeName = this.amesFrame.getNodeNameData(); int iNodeNumber = nodeName.length; boolean draw3DChart = false; this.dataset = new XYSeriesCollection(); DefaultCategoryDataset dataset3D = new DefaultCategoryDataset(); if ((selectIndex.length < 1) || (selectIndex[0] == 0)) { if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run (Selected Hour)")) { int iDayNumber = LMPByDay.size(); xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; double[][] lmp; for (int j = 0; j < iNodeNumber; j++) { XYSeries series = new XYSeries(nodeName[j]); for (int iDay = 0; iDay < iDayNumber; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); lmp = (double[][]) LMPByDay.get(iDay); series.add(iDay + 2, (Math.round(lmp[iDayHour][j] * 1000)) / 1000.0); if (hasSolutions[iDayHour] == 0) { noSolutionSeries.add(iDay + 2, 0.0); bNoSolution = true; } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } this.chartTitle = this.chartTitle + "\n " + "for Entire Run (At Hour " + iDayHour + ":00)"; } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day (Selected Hour)")) { xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; double[][] lmp; for (int j = 0; j < iNodeNumber; j++) { XYSeries series = new XYSeries(nodeName[j]); for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); lmp = (double[][]) LMPByDay.get(iDay); series.add(iDay + 2, (Math.round(lmp[iDayHour][j] * 1000)) / 1000.0); if (hasSolutions[iDayHour] == 0) { noSolutionSeries.add(iDay + 2, 0.0); bNoSolution = true; } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } this.chartTitle = this.chartTitle + "\n " + "From Day " + (iStartTime + 1) + " to Day " + (iEndTime + 1) + " (At Hour " + iDayHour + ":00)"; } else if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run (All Hours)")) { int iDayNumber = LMPByDay.size(); xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; double[][] lmp; for (int j = 0; j < iNodeNumber; j++) { XYSeries series = new XYSeries(nodeName[j]); for (int iDay = 0; iDay < iDayNumber; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); lmp = (double[][]) LMPByDay.get(iDay); for (int i = 0; i < 24; i++) { series.add(iDay + 1 + (i / 24.0), (Math.round(lmp[i][j] * 1000)) / 1000.0); if (hasSolutions[i] == 0) { noSolutionSeries.add(iDay + 1 + (i / 24.0), 0.0); bNoSolution = true; } } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } this.chartTitle = this.chartTitle + "\n " + "for Entire Run (All Hours)"; } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day (All Hours)")) { xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; double[][] lmp; for (int j = 0; j < iNodeNumber; j++) { XYSeries series = new XYSeries(nodeName[j]); for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); lmp = (double[][]) LMPByDay.get(iDay); for (int i = 0; i < 24; i++) { series.add(iDay + 1 + (i / 24.0), (Math.round(lmp[i][j] * 1000)) / 1000.0); if (hasSolutions[i] == 0) { noSolutionSeries.add(iDay + 1 + (i / 24.0), 0.0); bNoSolution = true; } } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } this.chartTitle = this.chartTitle + "\n " + "From Day " + (iStartTime + 1) + " to Day " + (iEndTime + 1) + " (All Hours)"; } } else { int iDataNumber = selectIndex.length; if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run (Selected Hour)")) { int iDayNumber = LMPByDay.size(); xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; double[][] lmp; for (int j = 0; j < iDataNumber; j++) { XYSeries series = new XYSeries(nodeName[selectIndex[j] - 1]); for (int iDay = 0; iDay < iDayNumber; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); lmp = (double[][]) LMPByDay.get(iDay); series.add(iDay + 2, (Math.round(lmp[iDayHour][selectIndex[j] - 1] * 1000)) / 1000.0); if (hasSolutions[iDayHour] == 0) { noSolutionSeries.add(iDay + 2, 0.0); bNoSolution = true; } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } this.chartTitle = this.chartTitle + "\n " + "for Entire Run (At Hour " + iDayHour + ":00)"; } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day (Selected Hour)")) { xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; double[][] lmp; for (int j = 0; j < iDataNumber; j++) { XYSeries series = new XYSeries(nodeName[selectIndex[j] - 1]); for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); lmp = (double[][]) LMPByDay.get(iDay); series.add(iDay + 2, (Math.round(lmp[iDayHour][selectIndex[j] - 1] * 1000)) / 1000.0); if (hasSolutions[iDayHour] == 0) { noSolutionSeries.add(iDay + 2, 0.0); bNoSolution = true; } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } this.chartTitle = this.chartTitle + "\n " + "From Day " + (iStartTime + 1) + " to Day " + (iEndTime + 1) + " (At Hour " + iDayHour + ":00)"; } else if (outputTimeTypeSelect.equalsIgnoreCase("Entire Run (All Hours)")) { int iDayNumber = LMPByDay.size(); xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; double[][] lmp; for (int j = 0; j < iDataNumber; j++) { XYSeries series = new XYSeries(nodeName[selectIndex[j] - 1]); for (int iDay = 0; iDay < iDayNumber; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); lmp = (double[][]) LMPByDay.get(iDay); for (int i = 0; i < 24; i++) { series.add(iDay + 1 + (i / 24.0), (Math.round(lmp[i][selectIndex[j] - 1] * 1000)) / 1000.0); if (hasSolutions[i] == 0) { noSolutionSeries.add(iDay + 1 + (i / 24.0), 0.0); bNoSolution = true; } } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } this.chartTitle = this.chartTitle + "\n " + "for Entire Run (All Hours)"; } else if (outputTimeTypeSelect.equalsIgnoreCase("Start to End Day (All Hours)")) { xLabel = "Day"; XYSeries noSolutionSeries = new XYSeries("No solution"); this.dataset.addSeries(noSolutionSeries); boolean bNoSolution = false; double[][] lmp; for (int j = 0; j < iDataNumber; j++) { XYSeries series = new XYSeries(nodeName[selectIndex[j] - 1]); for (int iDay = iStartTime - 1; iDay < iEndTime; iDay++) { hasSolutions = (int[]) hasSolutionByDay.get(iDay); lmp = (double[][]) LMPByDay.get(iDay); for (int i = 0; i < 24; i++) { series.add(iDay + 1 + (i / 24.0), (Math.round(lmp[i][selectIndex[j] - 1] * 1000)) / 1000.0); if (hasSolutions[i] == 0) { noSolutionSeries.add(iDay + 1 + (i / 24.0), 0.0); bNoSolution = true; } } } this.dataset.addSeries(series); } if (!bNoSolution) { this.dataset.removeSeries(noSolutionSeries); } this.chartTitle = this.chartTitle + "\n " + "From Day " + (iStartTime + 1) + " to Day " + (iEndTime + 1) + " (All Hours)"; } } // create the chart... this.chart = ChartFactory.createXYLineChart(this.chartTitle, // chart title xLabel, // x axis label "Price ($/MWh)", // y axis label this.dataset, // data PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls ); this.chart.setBackgroundPaint(Color.white); // get a reference to the plot for further customisation... final XYPlot plot = this.chart.getXYPlot(); plot.setBackgroundPaint(Color.white); plot.setDomainGridlinePaint(Color.blue); plot.setRangeGridlinePaint(Color.blue); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); XYToolTipGenerator generator = new StandardXYToolTipGenerator("{2}", new DecimalFormat("0.00"), new DecimalFormat("0.00")); renderer.setToolTipGenerator(generator); plot.setRenderer(renderer); NumberAxis xAxis = (NumberAxis) plot.getDomainAxis(); xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); this.chart.getTitle().setFont(this.font); this.chartPanel.setChart(this.chart); } public void setAMESFrame(AMESFrame frame) { this.amesFrame = frame; } public void setChartTitle(String title) { this.chartTitle = title; } public void setXLabel(String label) { this.xLabel = label; } public void setYLabel(String label) { this.xLabel = label; } public void setbackgroundColor(Color newColor) { Plot plot = this.chart.getPlot(); plot.setBackgroundPaint(newColor); } public void setGridLineColor(Color newColor) { Plot plot = this.chart.getPlot(); if (plot instanceof XYPlot) { XYPlot xyPlot = (XYPlot) plot; xyPlot.setDomainGridlinePaint(newColor); xyPlot.setRangeGridlinePaint(newColor); } } private String chartTitle; private String xLabel; private String yLabel; private XYSeriesCollection dataset; private JFreeChart chart; private ChartPanel chartPanel; private Font font = new Font("Times New Roman", Font.BOLD, 20); private AMESFrame amesFrame; }