consolidate card type and color distribution stats into single fixed-size StatsTable (closes #692).

master
lodici 2016-02-16 12:28:21 +00:00
parent 062afaf423
commit 0ee0a7d716
6 changed files with 239 additions and 40 deletions

View File

@ -84,7 +84,15 @@ public class CardStatistics {
public final int[] colorCount=new int[MagicColor.NR_COLORS];
public final int[] colorMono=new int[MagicColor.NR_COLORS];
public final int[] colorLands=new int[MagicColor.NR_COLORS];
public final int[] colorArtifacts=new int[MagicColor.NR_COLORS];
public final int[] colorCreatures=new int[MagicColor.NR_COLORS];
public final int[] colorEnchantments=new int[MagicColor.NR_COLORS];
public final int[] colorInstants=new int[MagicColor.NR_COLORS];
public final int[] colorSorcery=new int[MagicColor.NR_COLORS];
public final int[] colorPlaneswalkers=new int[MagicColor.NR_COLORS];
public final int[] manaCurve=new int[MANA_CURVE_SIZE];
public int monoColor;
public int multiColor;
@ -96,24 +104,63 @@ public class CardStatistics {
}
private void createStatistics() {
for (final MagicCardDefinition card : cards) {
//ignore tokens
if (card.isToken()) {
continue;
}
totalCards++;
totalRarity[card.getRarity()]++;
if (card.isLand()) {
totalTypes[0]++;
for (final MagicColor color : MagicColor.values()) {
if (card.getManaSource(color) > 0) {
colorLands[color.ordinal()]++;
int count = 0;
int index = -1;
for (final MagicColor color : MagicColor.values()) {
if (color.hasColor(card.getColorFlags())) {
index = color.ordinal();
colorCount[index]++;
count++;
}
if (card.isLand() && card.getManaSource(color) > 0) {
colorLands[color.ordinal()]++;
}
if (card.hasColor(color)) {
if (card.isCreature()) {
colorCreatures[color.ordinal()]++;
}
if (card.isArtifact()) {
colorArtifacts[color.ordinal()]++;
}
if (card.isEnchantment()) {
colorEnchantments[color.ordinal()]++;
}
if (card.isInstant()) {
colorInstants[color.ordinal()]++;
}
if (card.isSorcery()) {
colorSorcery[color.ordinal()]++;
}
if (card.isPlaneswalker()) {
colorPlaneswalkers[color.ordinal()]++;
}
}
}
if (count == 0) {
colorless++;
} else if (count == 1) {
colorMono[index]++;
monoColor++;
} else {
multiColor++;
}
if (card.hasX()) {
manaCurve[0]++;
} else if (card.getCost() != MagicManaCost.NONE) {
@ -124,6 +171,9 @@ public class CardStatistics {
averageCost += card.getConvertedCost();
averageValue += card.getValue();
if (card.isLand()) {
totalTypes[0]++;
}
if (card.isCreature()) {
totalTypes[1]++;
}
@ -143,24 +193,6 @@ public class CardStatistics {
totalTypes[6]++;
}
int count = 0;
int index = -1;
for (final MagicColor color : MagicColor.values()) {
if (color.hasColor(card.getColorFlags())) {
index = color.ordinal();
colorCount[index]++;
count++;
}
}
if (count == 0) {
colorless++;
} else if (count == 1) {
colorMono[index]++;
monoColor++;
} else {
multiColor++;
}
}
final int total=totalCards-totalTypes[0];

View File

@ -235,6 +235,7 @@ public enum MagicIcon {
public static final Set<MagicIcon> COLOR_MANA = EnumSet.range(MANA_WHITE, MANA_GREEN);
public static final Set<MagicIcon> HYBRID_COLOR_MANA = EnumSet.range(MANA_WHITE_BLUE, MANA_GREEN_BLUE);
private static final Set<MagicIcon> MANA_ICONS = EnumSet.range(MANA_UNTAP, MANA_X);
public static final Set<MagicIcon> TYPE_ICONS = EnumSet.of(LAND, CREATURE, ARTIFACT, ENCHANTMENT, INSTANT, SORCERY, PLANESWALKER);
private final String iconFilename;

View File

@ -33,9 +33,8 @@ public class DeckStatisticsViewer extends JPanel implements ChangeListener {
private final ActionButtonTitleBar titleBar;
private final ManaCurvePanel manaCurvePanel;
private final CardTypeStatsPanel cardTypesPanel;
private final CardColorStatsPanel colorsPanel;
private final ActionBarButton titlebarButton;
private final StatsTable statsTable;
public DeckStatisticsViewer() {
@ -44,9 +43,8 @@ public class DeckStatisticsViewer extends JPanel implements ChangeListener {
titlebarButton = getLogViewActionButton();
titleBar = new ActionButtonTitleBar(UiString.get(_S1), getLogActionButtons());
cardTypesPanel = new CardTypeStatsPanel();
statsTable = new StatsTable();
manaCurvePanel = new ManaCurvePanel();
colorsPanel = new CardColorStatsPanel();
setStatsVisible(GeneralConfig.getInstance().isStatsVisible());
setLayout(new MigLayout("flowy, insets 0, gap 0"));
@ -56,16 +54,14 @@ public class DeckStatisticsViewer extends JPanel implements ChangeListener {
private void refreshLayout() {
removeAll();
add(titleBar, "w 100%");
add(cardTypesPanel, "alignx center, gaptop 2, hidemode 3");
add(manaCurvePanel, "alignx center, gaptop 2, hidemode 3");
add(colorsPanel, "w 100%, gaptop 2, hidemode 3");
add(statsTable, "w 100%, hidemode 3");
add(manaCurvePanel, "alignx center, gaptop 2, gapbottom 4, hidemode 3");
revalidate();
}
private void setStatsVisible(boolean b) {
cardTypesPanel.setVisible(b);
statsTable.setVisible(b);
manaCurvePanel.setVisible(b);
colorsPanel.setVisible(b);
titlebarButton.setIcon(b
? MagicImages.getIcon(MagicIcon.DOWNARROW_ICON)
: MagicImages.getIcon(MagicIcon.UPARROW_ICON)
@ -108,8 +104,7 @@ public class DeckStatisticsViewer extends JPanel implements ChangeListener {
);
titleBar.setText(UiString.get(_S2, statistics.totalCards));
cardTypesPanel.setStats(statistics);
colorsPanel.setStats(statistics);
statsTable.setStats(statistics);
manaCurvePanel.setStats(statistics);
revalidate();

View File

@ -6,15 +6,12 @@ import javax.swing.JLabel;
import javax.swing.JPanel;
import magic.data.CardStatistics;
import magic.data.MagicIcon;
import magic.translate.UiString;
import magic.ui.MagicImages;
import net.miginfocom.swing.MigLayout;
@SuppressWarnings("serial")
class ManaCurvePanel extends JPanel {
private static final String _S1 = "Mana curve";
private final ManaCurveUnitPanel[] manaPanels;
ManaCurvePanel() {
@ -27,8 +24,6 @@ class ManaCurvePanel extends JPanel {
setLayout(new MigLayout("insets 0, gap 0"));
add(DeckStatisticsViewer.getCaptionLabel(UiString.get(_S1)), "w 100%, wrap, span");
for (int i = 0; i < CardStatistics.MANA_CURVE_SIZE; i++) {
final MagicIcon manaSymbol = CardStatistics.MANA_CURVE_ICONS.get(i);

View File

@ -0,0 +1,164 @@
package magic.ui.deck.stats;
import java.awt.Color;
import java.awt.Image;
import java.util.HashMap;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import magic.data.CardStatistics;
import magic.data.MagicIcon;
import magic.model.MagicColor;
import magic.ui.MagicImages;
import magic.ui.utility.GraphicsUtils;
import net.miginfocom.swing.MigLayout;
@SuppressWarnings("serial")
class StatsTable extends JPanel {
private static final ImageIcon[] manaIconOn = new ImageIcon[MagicColor.values().length];
private static final ImageIcon[] manaIconOff = new ImageIcon[MagicColor.values().length];
private static final Map<MagicIcon, ImageIcon> typeIconOff = new HashMap<>();
static {
setManaIcons();
setTypeOffIcons();
}
StatsTable() {
setOpaque(false);
setLayout(new MigLayout("flowy, insets 0 2 2 2, gap 0"));
}
private static void setManaIcons() {
for (MagicColor color : MagicColor.values()) {
final ImageIcon colorIcon = MagicImages.getIcon(color.getManaType());
manaIconOn[color.ordinal()] = colorIcon;
final Image gsImage = GraphicsUtils.getGreyScaleImage(colorIcon.getImage());
manaIconOff[color.ordinal()] = new ImageIcon(GraphicsUtils.getTranslucentImage(gsImage, 0.3f));
}
}
private static void setTypeOffIcons() {
for (MagicIcon icon : MagicIcon.TYPE_ICONS) {
final ImageIcon colorIcon = MagicImages.getIcon(icon);
final Image fadedImage = GraphicsUtils.getTranslucentImage(colorIcon.getImage(), 0.2f);
typeIconOff.put(icon, new ImageIcon(fadedImage));
}
}
private JLabel getLabel(String text, boolean isEnabled) {
JLabel lbl = new JLabel(isEnabled ? text : "—");
lbl.setForeground(!isEnabled ? Color.LIGHT_GRAY : lbl.getForeground());
return lbl;
}
private JLabel getValueLabel(int value, boolean isEnabled) {
JLabel lbl = getLabel(Integer.toString(value), isEnabled);
lbl.setForeground(value == 0 && isEnabled ? Color.GRAY : lbl.getForeground());
return lbl;
}
private JLabel getValueLabel(int value) {
return getValueLabel(value, value > 0);
}
private JLabel getPercentageLabel(CardStatistics stats, int total) {
final int percentage = (int) Math.round(((double) total / stats.totalCards) * 100);
JLabel lbl = getValueLabel(percentage, percentage > 0);
lbl.setFont(lbl.getFont().deriveFont(10f));
return lbl;
}
private JLabel getHeadingLabel(MagicIcon icon, String tooltip, int value) {
JLabel lbl = new JLabel(value == 0 ? typeIconOff.get(icon) : MagicImages.getIcon(icon));
lbl.setToolTipText(tooltip);
return lbl;
}
private JLabel getHeadingLabel(String text, String tooltip) {
JLabel lbl = new JLabel(text);
lbl.setToolTipText(tooltip);
return lbl;
}
void setStats(CardStatistics stats) {
final MigLayout mig = new MigLayout("wrap 12, gapx 5");
mig.setColumnConstraints("[center][20!, center]");
mig.setRowConstraints("[][]0[]6[][]");
final JPanel panel = new JPanel(mig);
panel.setOpaque(false);
// headings
panel.add(new JLabel());
panel.add(getHeadingLabel("Σ", "Total cards"));
panel.add(getHeadingLabel(MagicIcon.LAND, "Land", stats.totalTypes[0]));
panel.add(getHeadingLabel(MagicIcon.CREATURE, "Creature", stats.totalTypes[1]));
panel.add(getHeadingLabel(MagicIcon.ARTIFACT, "Artifact", stats.totalTypes[2]));
panel.add(getHeadingLabel(MagicIcon.ENCHANTMENT, "Enchantment", stats.totalTypes[3]));
panel.add(getHeadingLabel(MagicIcon.INSTANT, "Instant", stats.totalTypes[4]));
panel.add(getHeadingLabel(MagicIcon.SORCERY, "Sorcery", stats.totalTypes[5]));
panel.add(getHeadingLabel(MagicIcon.PLANESWALKER, "Planeswalker", stats.totalTypes[6]));
panel.add(getHeadingLabel("=0", "Colorless"));
panel.add(getHeadingLabel("=1", "Mono-color"));
panel.add(getHeadingLabel(">1", "Multi-color"));
// totals
panel.add(new JLabel("Σ"));
panel.add(getValueLabel(stats.totalCards));
panel.add(getValueLabel(stats.totalTypes[0]));
panel.add(getValueLabel(stats.totalTypes[1]));
panel.add(getValueLabel(stats.totalTypes[2]));
panel.add(getValueLabel(stats.totalTypes[3]));
panel.add(getValueLabel(stats.totalTypes[4]));
panel.add(getValueLabel(stats.totalTypes[5]));
panel.add(getValueLabel(stats.totalTypes[6]));
panel.add(getValueLabel(stats.colorless));
panel.add(getValueLabel(stats.monoColor));
panel.add(getValueLabel(stats.multiColor));
// %
panel.add(new JLabel("%"));
panel.add(getPercentageLabel(stats, stats.totalCards));
panel.add(getPercentageLabel(stats, stats.totalTypes[0]));
panel.add(getPercentageLabel(stats, stats.totalTypes[1]));
panel.add(getPercentageLabel(stats, stats.totalTypes[2]));
panel.add(getPercentageLabel(stats, stats.totalTypes[3]));
panel.add(getPercentageLabel(stats, stats.totalTypes[4]));
panel.add(getPercentageLabel(stats, stats.totalTypes[5]));
panel.add(getPercentageLabel(stats, stats.totalTypes[6]));
panel.add(getPercentageLabel(stats, stats.colorless));
panel.add(getPercentageLabel(stats, stats.monoColor));
panel.add(getPercentageLabel(stats, stats.multiColor));
for (int i = 0; i < stats.colorCount.length; i++) {
final boolean hasColor = stats.colorCount[i] > 0;
final JLabel label = new JLabel();
if (hasColor) {
label.setIcon(manaIconOn[i]);
} else {
label.setIcon(manaIconOff[i]);
label.setForeground(Color.GRAY);
}
panel.add(label);
panel.add(getValueLabel(stats.colorCount[i], hasColor));
panel.add(getValueLabel(stats.colorLands[i], hasColor && stats.totalTypes[0] > 0));
panel.add(getValueLabel(stats.colorCreatures[i], hasColor && stats.totalTypes[1] > 0));
panel.add(getValueLabel(stats.colorArtifacts[i], hasColor && stats.totalTypes[2] > 0));
panel.add(getValueLabel(stats.colorEnchantments[i], hasColor && stats.totalTypes[3] > 0));
panel.add(getValueLabel(stats.colorInstants[i], hasColor && stats.totalTypes[4] > 0));
panel.add(getValueLabel(stats.colorSorcery[i], hasColor && stats.totalTypes[5] > 0));
panel.add(getValueLabel(stats.colorPlaneswalkers[i], hasColor && stats.totalTypes[6] > 0));
panel.add(getLabel("---", false));
panel.add(getValueLabel(stats.colorMono[i], hasColor));
panel.add(getLabel("---", false));
}
removeAll();
add(panel, "w 100%");
revalidate();
}
}

View File

@ -303,6 +303,18 @@ final public class GraphicsUtils {
return newImage;
}
public static Image getTranslucentImage(Image image, float opacity) {
final BufferedImage newImage = getCompatibleBufferedImage(
image.getWidth(null), image.getHeight(null), Transparency.TRANSLUCENT
);
final Graphics2D g2d = newImage.createGraphics();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
g2d.drawImage(image, 0, 0, null);
g2d.dispose();
return newImage;
}
/**
* Returns an optimized subimage defined by a specified rectangular region.
* <p>