optaplanner-benchmark/src/main/java/org/optaplanner/benchmark/impl/statistic/subsingle/constraintmatchtotalbestscore/ConstraintMatchTotalBestScoreSubSingleStatistic.java
@Override
    public void writeGraphFiles(BenchmarkReport benchmarkReport) {
        List<Map<String, XYSeries>> constraintIdToWeightSeriesMapList
                = new ArrayList<>(BenchmarkReport.CHARTED_SCORE_LEVEL_SIZE);
        for (ConstraintMatchTotalBestScoreStatisticPoint point : getPointList()) {
            long timeMillisSpent = point.getTimeMillisSpent();
            double[] levelValues = ScoreUtils.extractLevelDoubles(point.getScoreTotal());
            for (int i = 0; i < levelValues.length && i < BenchmarkReport.CHARTED_SCORE_LEVEL_SIZE; i++) {
                if (i >= constraintIdToWeightSeriesMapList.size()) {
                    constraintIdToWeightSeriesMapList.add(new LinkedHashMap<>());
                }
                Map<String, XYSeries> constraintIdToWeightSeriesMap = constraintIdToWeightSeriesMapList.get(i);
                XYSeries weightSeries = constraintIdToWeightSeriesMap.computeIfAbsent(point.getConstraintId(),
                        k -> new XYSeries(point.getConstraintName() + " weight"));
                // Only add changes
                if (levelValues[i] != ((weightSeries.getItemCount() == 0) ? 0.0
                        : weightSeries.getY(weightSeries.getItemCount() - 1).doubleValue())) {
                    weightSeries.add(timeMillisSpent, levelValues[i]);
                }
            }
        }
        long timeMillisSpent = subSingleBenchmarkResult.getTimeMillisSpent();
        for (Map<String, XYSeries> constraintIdToWeightSeriesMap : constraintIdToWeightSeriesMapList) {
            for (Iterator<Map.Entry<String, XYSeries>> it = constraintIdToWeightSeriesMap.entrySet().iterator(); it.hasNext(); ) {
                XYSeries weightSeries = it.next().getValue();
                if (weightSeries.getItemCount() == 0) {
                    // Only show the constraint type on the score levels that it affects
                    it.remove();
                } else {
                    // Draw a horizontal line from the last new best step to how long the solver actually ran
                    weightSeries.add(timeMillisSpent, weightSeries.getY(weightSeries.getItemCount() - 1).doubleValue());
                }
            }
        }
        graphFileList = new ArrayList<>(constraintIdToWeightSeriesMapList.size());
        for (int scoreLevelIndex = 0; scoreLevelIndex < constraintIdToWeightSeriesMapList.size(); scoreLevelIndex++) {
            XYPlot plot = createPlot(benchmarkReport, scoreLevelIndex);
            // No direct ascending lines between 2 points, but a stepping line instead
            XYItemRenderer renderer = new XYStepRenderer();
            plot.setRenderer(renderer);
            XYSeriesCollection seriesCollection = new XYSeriesCollection();
            for (XYSeries series : constraintIdToWeightSeriesMapList.get(scoreLevelIndex).values()) {
                seriesCollection.addSeries(series);
            }
            plot.setDataset(seriesCollection);
            String scoreLevelLabel = subSingleBenchmarkResult.getSingleBenchmarkResult().getProblemBenchmarkResult()
                    .findScoreLevelLabel(scoreLevelIndex);
            JFreeChart chart = new JFreeChart(subSingleBenchmarkResult.getName()
                    + " constraint match total best " + scoreLevelLabel + " diff statistic",
                    JFreeChart.DEFAULT_TITLE_FONT, plot, true);
            graphFileList.add(writeChartToImageFile(chart,
                    "ConstraintMatchTotalBestScoreStatisticLevel" + scoreLevelIndex));
        }
    }
@Override
    public void writeGraphFiles(BenchmarkReport benchmarkReport) {
        List<Map<String, XYSeries>> constraintIdToWeightSeriesMapList
                = new ArrayList<>(BenchmarkReport.CHARTED_SCORE_LEVEL_SIZE);
        for (ConstraintMatchTotalBestScoreStatisticPoint point : getPointList()) {
            long timeMillisSpent = point.getTimeMillisSpent();
            double[] levelValues = ScoreUtils.extractLevelDoubles(point.getScoreTotal());
            for (int i = 0; i < levelValues.length && i < BenchmarkReport.CHARTED_SCORE_LEVEL_SIZE; i++) {
                if (i >= constraintIdToWeightSeriesMapList.size()) {
                    constraintIdToWeightSeriesMapList.add(new LinkedHashMap<>());
                }
                Map<String, XYSeries> constraintIdToWeightSeriesMap = constraintIdToWeightSeriesMapList.get(i);
                XYSeries weightSeries = constraintIdToWeightSeriesMap.computeIfAbsent(point.getConstraintId(),
                        k -> new XYSeries(point.getConstraintName() + " weight"));
                // Only add changes
                if (levelValues[i] != ((weightSeries.getItemCount() == 0) ? 0.0
                        : weightSeries.getY(weightSeries.getItemCount() - 1).doubleValue())) {
                    weightSeries.add(timeMillisSpent, levelValues[i]);
                }
            }
        }
        long timeMillisSpent = subSingleBenchmarkResult.getTimeMillisSpent();
        for (Map<String, XYSeries> constraintIdToWeightSeriesMap : constraintIdToWeightSeriesMapList) {
            for (Iterator<Map.Entry<String, XYSeries>> it = constraintIdToWeightSeriesMap.entrySet().iterator(); it.hasNext(); ) {
                XYSeries weightSeries = it.next().getValue();
                if (weightSeries.getItemCount() == 0) {
                    // Only show the constraint type on the score levels that it affects
                    it.remove();
                } else {
                    // Draw a horizontal line from the last new best step to how long the solver actually ran
                    weightSeries.add(timeMillisSpent, weightSeries.getY(weightSeries.getItemCount() - 1).doubleValue());
                }
            }
        }
        graphFileList = new ArrayList<>(constraintIdToWeightSeriesMapList.size());
        for (int scoreLevelIndex = 0; scoreLevelIndex < constraintIdToWeightSeriesMapList.size(); scoreLevelIndex++) {
            XYPlot plot = createPlot(benchmarkReport, scoreLevelIndex);
            // No direct ascending lines between 2 points, but a stepping line instead
            XYItemRenderer renderer = new XYStepRenderer();
            plot.setRenderer(renderer);
            XYSeriesCollection seriesCollection = new XYSeriesCollection();
            for (XYSeries series : constraintIdToWeightSeriesMapList.get(scoreLevelIndex).values()) {
                seriesCollection.addSeries(series);
            }
            plot.setDataset(seriesCollection);
            String scoreLevelLabel = subSingleBenchmarkResult.getSingleBenchmarkResult().getProblemBenchmarkResult()
                    .findScoreLevelLabel(scoreLevelIndex);
            JFreeChart chart = new JFreeChart(subSingleBenchmarkResult.getName()
                    + " constraint match total best " + scoreLevelLabel + " diff statistic",
                    JFreeChart.DEFAULT_TITLE_FONT, plot, true);
            graphFileList.add(writeChartToImageFile(chart,
                    "ConstraintMatchTotalBestScoreStatisticLevel" + scoreLevelIndex));
        }
    }
@ Override public void writeGraphFiles ( BenchmarkReport benchmarkReport ) { List < Map < String , XYSeries > > constraintIdToWeightSeriesMapList = new ArrayList <> ( BenchmarkReport . CHARTED_SCORE_LEVEL_SIZE ) ; for ( ConstraintMatchTotalBestScoreStatisticPoint point : getPointList ( ) ) { long timeMillisSpent = point . getTimeMillisSpent ( ) ; double [ ] levelValues = ScoreUtils . extractLevelDoubles ( point . getScoreTotal ( ) ) ; for ( int i = 0 ; i < levelValues . length && i < BenchmarkReport . CHARTED_SCORE_LEVEL_SIZE ; i ++ ) { if ( i >= constraintIdToWeightSeriesMapList . size ( ) ) { constraintIdToWeightSeriesMapList . add ( new LinkedHashMap <> ( ) ) ; } Map < String , XYSeries > constraintIdToWeightSeriesMap = constraintIdToWeightSeriesMapList . get ( i ) ; XYSeries weightSeries = constraintIdToWeightSeriesMap . computeIfAbsent ( point . getConstraintId ( ) , k -> new XYSeries ( point . getConstraintName ( ) + " weight" ) ) ; // Only add changes if ( levelValues [ i ] != ( ( weightSeries . getItemCount ( ) == 0 ) ? 0.0 : weightSeries . getY ( weightSeries . getItemCount ( ) - 1 ) . doubleValue ( ) ) ) { weightSeries . add ( timeMillisSpent , levelValues [ i ] ) ; } } } long timeMillisSpent = subSingleBenchmarkResult . getTimeMillisSpent ( ) ; for ( Map < String , XYSeries > constraintIdToWeightSeriesMap : constraintIdToWeightSeriesMapList ) { for ( Iterator < Map . Entry < String , XYSeries > > it = constraintIdToWeightSeriesMap . entrySet ( ) . iterator ( ) ; it . hasNext ( ) ; ) { XYSeries weightSeries = it . next ( ) . getValue ( ) ; if ( weightSeries . getItemCount ( ) == 0 ) { // Only show the constraint type on the score levels that it affects it . remove ( ) ; } else { // Draw a horizontal line from the last new best step to how long the solver actually ran weightSeries . add ( timeMillisSpent , weightSeries . getY ( weightSeries . getItemCount ( ) - 1 ) . doubleValue ( ) ) ; } } } graphFileList = new ArrayList <> ( constraintIdToWeightSeriesMapList . size ( ) ) ; for ( int scoreLevelIndex = 0 ; scoreLevelIndex < constraintIdToWeightSeriesMapList . size ( ) ; scoreLevelIndex ++ ) { XYPlot plot = createPlot ( benchmarkReport , scoreLevelIndex ) ; // No direct ascending lines between 2 points, but a stepping line instead XYItemRenderer renderer = new XYStepRenderer ( ) ; plot . setRenderer ( renderer ) ; XYSeriesCollection seriesCollection = new XYSeriesCollection ( ) ; for ( XYSeries series : constraintIdToWeightSeriesMapList . get ( scoreLevelIndex ) . values ( ) ) { seriesCollection . addSeries ( series ) ; } plot . setDataset ( seriesCollection ) ; String scoreLevelLabel = subSingleBenchmarkResult . getSingleBenchmarkResult ( ) . getProblemBenchmarkResult ( ) . findScoreLevelLabel ( scoreLevelIndex ) ; JFreeChart chart = new JFreeChart ( subSingleBenchmarkResult . getName ( ) + " constraint match total best " + scoreLevelLabel + " diff statistic" , JFreeChart . DEFAULT_TITLE_FONT , plot , true ) ; graphFileList . add ( writeChartToImageFile ( chart , "ConstraintMatchTotalBestScoreStatisticLevel" + scoreLevelIndex ) ) ; } }
************************************************************************
************************************************************************