package info.opencards.ui.lastmin;
import info.opencards.Utils;
import info.opencards.core.Item;
import info.opencards.learnstrats.leitner.LeitnerItem;
import info.opencards.learnstrats.leitner.LeitnerListener;
import info.opencards.learnstrats.leitner.LeitnerSystem;
import info.opencards.learnstrats.leitner.LeitnerUtils;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.TickUnits;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.StandardCategoryToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.StackedBarRenderer;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.GradientPaintTransformType;
import org.jfree.ui.StandardGradientPaintTransformer;
import javax.swing.*;
import java.awt.*;
import java.util.ResourceBundle;
/**
* A panel which shows the current learning state of the the flashcards in the current presentation.
*
* @author Holger Brandl
*/
class LeitnerStatePanel extends JPanel implements LeitnerListener {
private LeitnerSystem myLeitnerSystem;
private DefaultCategoryDataset dataset;
private ValueAxis valueAxis;
private LeitnerItem hightlightItem;
private CategoryPlot plot;
public LeitnerStatePanel() {
setLayout(new BorderLayout());
}
public void setLeitnerSystem(LeitnerSystem leitnerSystem) {
assert leitnerSystem != null;
if (this.myLeitnerSystem != null)
this.myLeitnerSystem.removeLearnSessionChangeListener(this);
this.myLeitnerSystem = leitnerSystem;
this.myLeitnerSystem.addLearnSessionChangeListener(this);
// setup the stacked bar chart
dataset = new DefaultCategoryDataset();
final JFreeChart chart = ChartFactory.createStackedBarChart(
null, // chart title
null, // domain axis label
// "# cards", // range axis label
null, // range axis label
dataset, // data
PlotOrientation.VERTICAL, // the plot orientation
false, // legend
true, // tooltips
false // urls
);
plot = (CategoryPlot) chart.getPlot();
valueAxis = plot.getRangeAxis();
TickUnits units = (TickUnits) NumberAxis.createIntegerTickUnits();
valueAxis.setStandardTickUnits(units);
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPopupMenu(null);
chartPanel.setDomainZoomable(false);
chartPanel.setRangeZoomable(false);
removeAll();
add(chartPanel, BorderLayout.CENTER);
rebuildBoxBarchart();
}
private void reconfigureColorEncoding() {
StackedBarRenderer renderer = new StackedBarRenderer();
renderer.setGradientPaintTransformer(new StandardGradientPaintTransformer(GradientPaintTransformType.HORIZONTAL));
renderer.setItemMargin(0.0);
int barIndex = 0;
//blue
Paint p1 = new GradientPaint(0.0f, 0.0f, new Color(0x22, 0x22, 0xFF), 0.0f, 0.0f, new Color(0x88, 0x88, 0xFF));
renderer.setSeriesPaint(barIndex, p1);
renderer.setSeriesToolTipGenerator(barIndex, new StandardCategoryToolTipGenerator());
//green
barIndex++;
Paint p3 = new GradientPaint(0.0f, 0.0f, new Color(0x22, 0xFF, 0x22), 0.0f, 0.0f, new Color(0x88, 0xFF, 0x88));
renderer.setSeriesPaint(barIndex, p3);
renderer.setSeriesToolTipGenerator(barIndex, new StandardCategoryToolTipGenerator());
if (hightlightItem != null) {
//red
barIndex++;
Paint p2 = new GradientPaint(0.0f, 0.0f, new Color(0xFF, 0x22, 0x22), 0.0f, 0.0f, new Color(0xFF, 0x88, 0x88));
renderer.setSeriesPaint(barIndex, p2);
renderer.setSeriesToolTipGenerator(barIndex, new StandardCategoryToolTipGenerator());
}
plot.setRenderer(renderer);
}
private void rebuildBoxBarchart() {
dataset.clear();
reconfigureColorEncoding();
ResourceBundle rb = Utils.getRB();
// System.out.println("cur boxes state:\n" + LeitnerUtils.print(myLeitnerSystem));
for (int i = 0; i < myLeitnerSystem.numBoxes(); i++) {
java.util.List<LeitnerItem> flashCards = myLeitnerSystem.getBoxes().get(i);
int numLearnt = LeitnerUtils.count(flashCards, LeitnerSystem.LEARNT);
int numFailed = LeitnerUtils.count(flashCards, LeitnerSystem.FAILED);
int numUnknown = LeitnerUtils.count(flashCards, LeitnerSystem.NEW);
int boxIndex = i + 1;
String boxName = myLeitnerSystem.numBoxes() > 5 ? boxIndex + "" : rb.getString("LeitnerStatePanel.box") + " " + boxIndex;
if (hightlightItem != null & myLeitnerSystem.getBoxIndex(hightlightItem) == i) {
if (hightlightItem.getState() == LeitnerSystem.NEW)
numUnknown--;
else
numLearnt--;
}
dataset.addValue(numUnknown, "New flashcards", boxName);
// dataset.addValue(numFailed, "Failed", boxName);
dataset.addValue(numLearnt + numFailed, "Learnt", boxName);
if (hightlightItem != null) {
if (myLeitnerSystem.getBoxIndex(hightlightItem) == i) {
dataset.addValue(1, "Current flashcard", boxName);
} else {
dataset.addValue(0, "Current flashcard", boxName);
}
}
}
valueAxis.setLowerBound(0);
valueAxis.setUpperBound(Math.max(myLeitnerSystem.getAllCards().size(), 1) * 1.1);
valueAxis.setAutoRange(false);
revalidate();
}
public void newCard(Item flashcard) {
rebuildBoxBarchart();
}
public void boxingChanged(Item... movedCards) {
rebuildBoxBarchart();
}
public void removedCard(Item flashcard) {
rebuildBoxBarchart();
}
/**
* Highlights an item of a leitner system.
*/
public void higlightItem(Item item) {
assert item instanceof LeitnerItem;
this.hightlightItem = (LeitnerItem) item;
rebuildBoxBarchart();
}
}