diff --git a/src/app/components/Defence.jsx b/src/app/components/Defence.jsx
index 7c9c0dfe..cb9bdf82 100644
--- a/src/app/components/Defence.jsx
+++ b/src/app/components/Defence.jsx
@@ -233,16 +233,12 @@ export default class Defence extends TranslatedComponent {
const shieldSourcesData = [];
const effectiveShieldData = [];
- const damageTakenData = [];
+ const shieldDamageTakenData = [];
const shieldTooltipDetails = [];
const shieldAbsoluteTooltipDetails = [];
const shieldExplosiveTooltipDetails = [];
const shieldKineticTooltipDetails = [];
const shieldThermalTooltipDetails = [];
- let effectiveAbsoluteShield = 0;
- let effectiveExplosiveShield = 0;
- let effectiveKineticShield = 0;
- let effectiveThermalShield = 0;
if (shield.total) {
if (Math.round(shield.generator) > 0) shieldSourcesData.push({ value: Math.round(shield.generator), label: translate('generator') });
if (Math.round(shield.boosters) > 0) shieldSourcesData.push({ value: Math.round(shield.boosters), label: translate('boosters') });
@@ -268,24 +264,24 @@ export default class Defence extends TranslatedComponent {
shieldThermalTooltipDetails.push(
{translate('boosters') + ' ' + formats.pct1(shield.thermal.boosters)}
);
shieldThermalTooltipDetails.push({translate('power distributor') + ' ' + formats.pct1(shield.thermal.sys)}
);
- effectiveAbsoluteShield = shield.total / shield.absolute.total;
+ const effectiveAbsoluteShield = shield.total / shield.absolute.total;
effectiveShieldData.push({ value: Math.round(effectiveAbsoluteShield), label: translate('absolute') });
- effectiveExplosiveShield = shield.total / shield.explosive.total;
+ const effectiveExplosiveShield = shield.total / shield.explosive.total;
effectiveShieldData.push({ value: Math.round(effectiveExplosiveShield), label: translate('explosive') });
- effectiveKineticShield = shield.total / shield.kinetic.total;
+ const effectiveKineticShield = shield.total / shield.kinetic.total;
effectiveShieldData.push({ value: Math.round(effectiveKineticShield), label: translate('kinetic') });
- effectiveThermalShield = shield.total / shield.thermal.total;
+ const effectiveThermalShield = shield.total / shield.thermal.total;
effectiveShieldData.push({ value: Math.round(effectiveThermalShield), label: translate('thermal') });
- damageTakenData.push({ value: Math.round(shield.absolute.total * 100), label: translate('absolute') });
- damageTakenData.push({ value: Math.round(shield.explosive.total * 100), label: translate('explosive') });
- damageTakenData.push({ value: Math.round(shield.kinetic.total * 100), label: translate('kinetic') });
- damageTakenData.push({ value: Math.round(shield.thermal.total * 100), label: translate('thermal') });
+ shieldDamageTakenData.push({ value: Math.round(shield.absolute.total * 100), label: translate('absolute') });
+ shieldDamageTakenData.push({ value: Math.round(shield.explosive.total * 100), label: translate('explosive') });
+ shieldDamageTakenData.push({ value: Math.round(shield.kinetic.total * 100), label: translate('kinetic') });
+ shieldDamageTakenData.push({ value: Math.round(shield.thermal.total * 100), label: translate('thermal') });
}
- const armourData = [];
- if (Math.round(armour.bulkheads) > 0) armourData.push({ value: Math.round(armour.bulkheads), label: translate('bulkheads') });
- if (Math.round(armour.reinforcement) > 0) armourData.push({ value: Math.round(armour.reinforcement), label: translate('reinforcement') });
+ const armourSourcesData = [];
+ if (Math.round(armour.bulkheads) > 0) armourSourcesData.push({ value: Math.round(armour.bulkheads), label: translate('bulkheads') });
+ if (Math.round(armour.reinforcement) > 0) armourSourcesData.push({ value: Math.round(armour.reinforcement), label: translate('reinforcement') });
const armourTooltipDetails = [];
if (armour.bulkheads > 0) armourTooltipDetails.push({translate('bulkheads') + ' ' + formats.int(armour.bulkheads)}
);
@@ -307,55 +303,64 @@ export default class Defence extends TranslatedComponent {
armourThermalTooltipDetails.push({translate('bulkheads') + ' ' + formats.pct1(armour.thermal.bulkheads)}
);
armourThermalTooltipDetails.push({translate('reinforcement') + ' ' + formats.pct1(armour.thermal.reinforcement)}
);
+ const effectiveArmourData = [];
+ const effectiveAbsoluteArmour = armour.total / armour.absolute.total;
+ effectiveArmourData.push({ value: Math.round(effectiveAbsoluteArmour), label: translate('absolute') });
+ const effectiveExplosiveArmour = armour.total / armour.explosive.total;
+ effectiveArmourData.push({ value: Math.round(effectiveExplosiveArmour), label: translate('explosive') });
+ const effectiveKineticArmour = armour.total / armour.kinetic.total;
+ effectiveArmourData.push({ value: Math.round(effectiveKineticArmour), label: translate('kinetic') });
+ const effectiveThermalArmour = armour.total / armour.thermal.total;
+ effectiveArmourData.push({ value: Math.round(effectiveThermalArmour), label: translate('thermal') });
+
+ // TODO these aren't updating when HRP metrics are altered (maybe - need to confirm)
+ const armourDamageTakenData = [];
+ armourDamageTakenData.push({ value: Math.round(armour.absolute.total * 100), label: translate('absolute') });
+ armourDamageTakenData.push({ value: Math.round(armour.explosive.total * 100), label: translate('explosive') });
+ armourDamageTakenData.push({ value: Math.round(armour.kinetic.total * 100), label: translate('kinetic') });
+ armourDamageTakenData.push({ value: Math.round(armour.thermal.total * 100), label: translate('thermal') });
+
+ // TODO versions of ship.calcShieldRecovery() and ship.calcShieldRecharge() that take account of SYS pips
return (
{shield.total ?
-
-
-
{shieldTooltipDetails}
)} onMouseOut={tooltip.bind(null, null)} className='summary'>{translate('shields')}: {formats.int(shield.total)}{units.MJ}
-
{translate('PHRASE_TIME_TO_LOSE_SHIELDS')} {formats.time(shield.total / shielddamage.totalsdps)}
-
-
-
{translate('shield sources')}
-
-
+
+
{translate('shield metrics')}
+
+ {shieldTooltipDetails}
)} onMouseOut={tooltip.bind(null, null)} className='summary'>{translate('raw shield strength')}: {formats.int(shield.total)}{units.MJ}
+ {translate('PHRASE_TIME_TO_LOSE_SHIELDS')} {formats.time(shield.total / shielddamage.totalsdps)}
+ {translate('PHRASE_TIME_TO_RECOVER_SHIELDS')} {formats.time(ship.calcShieldRecovery())}
+ {translate('PHRASE_TIME_TO_RECHARGE_SHIELDS')} {formats.time(ship.calcShieldRecharge())}
-
-
-
{translate('effective shield')}(MJ)
-
-
-
-
{translate('damage taken')}(%)
-
-
-
: null }
+
+
{translate('shield sources')}
+
+
+
+
{translate('effective shield')}(MJ)
+
+
+
+
{translate('damage taken')}(%)
+
+
+ : null }
-
-
{armourTooltipDetails}
)} onMouseOut={tooltip.bind(null, null)} className='summary'>{translate('armour')}: {formats.int(armour.total)}
-
-
-
- | {translate('damage taken')} |
-
- {armourAbsoluteTooltipDetails})} onMouseOut={tooltip.bind(null, null)}>{formats.pct1(armour.absolute.total)}
- |
-
- {armourExplosiveTooltipDetails})} onMouseOut={tooltip.bind(null, null)}>{formats.pct1(armour.explosive.total)}
- |
-
- {armourKineticTooltipDetails})} onMouseOut={tooltip.bind(null, null)}>{formats.pct1(armour.kinetic.total)}
- |
-
- {armourThermalTooltipDetails})} onMouseOut={tooltip.bind(null, null)}>{formats.pct1(armour.thermal.total)}
- |
-
-
-
+
+
{translate('armour metrics')}
+
-
-
{translate('armour sources')}
-
+
+
{translate('armour sources')}
+
+
+
+
{translate('effective armour')}
+
+
+
+
{translate('damage taken')}(%)
+
);
}
diff --git a/src/app/components/VerticalBarChart.jsx b/src/app/components/VerticalBarChart.jsx
index 9bbab161..34166491 100644
--- a/src/app/components/VerticalBarChart.jsx
+++ b/src/app/components/VerticalBarChart.jsx
@@ -20,7 +20,7 @@ export default class VerticalBarChart extends Component {
static propTypes = {
data : React.PropTypes.array.isRequired,
- ylabel : React.PropTypes.string
+ yMax : React.PropTypes.number
};
/**
@@ -57,7 +57,13 @@ export default class VerticalBarChart extends Component {
// Y axis is a numeric scale with values being 'value'
this.y = d3.scaleLinear();
- this.y.domain([0, d3.max(this.props.data, d => d.value)]);
+ if (props.yMax) {
+ // Fixed maximum value (unless we go off the scale)
+ const localMax = d3.max(this.props.data, d => d.value);
+ this.y.domain([0, localMax > props.yMax ? localMax : props.yMax]);
+ } else {
+ this.y.domain([0, d3.max(this.props.data, d => d.value)]);
+ }
this.yAxis = d3.axisLeft(this.y);
this.y.range([height, 0]);
diff --git a/src/app/i18n/en.js b/src/app/i18n/en.js
index 7cce1ea2..74e2a3b2 100644
--- a/src/app/i18n/en.js
+++ b/src/app/i18n/en.js
@@ -25,7 +25,7 @@ export const terms = {
PHRASE_NO_RETROCH: 'No Retrofitting changes',
PHRASE_SELECT_BUILDS: 'Select builds to compare',
PHRASE_SG_RECHARGE: 'Time from 50% to 100% charge',
- PHRASE_SG_RECOVER: 'Recovery (to 50%) after collapse',
+ PHRASE_SG_RECOVER: 'Time from 0% to 50% charge',
PHRASE_UNLADEN: 'Ship mass excluding fuel and cargo',
PHRASE_UPDATE_RDY: 'Update Available! Click to refresh',
PHRASE_ENGAGEMENT_RANGE: 'The distance between your ship and its target',
@@ -40,6 +40,13 @@ export const terms = {
PHRASE_SHOPPING_LIST: 'Stations that sell this build',
PHRASE_TOTAL_EFFECTIVE_SHIELD: 'Total amount of damage that can be taken from each damage type, if using all shield cells',
PHRASE_TIME_TO_LOSE_SHIELDS: 'Shields will hold for',
+ PHRASE_TIME_TO_RECOVER_SHIELDS: 'Shields will recover in',
+ PHRASE_TIME_TO_RECHARGE_SHIELDS: 'Shields will recharge in',
+ PHRASE_SHIELD_SOURCES: 'Breakdown of the supply of shield energy',
+ PHRASE_EFFECTIVE_SHIELD: 'Effective shield strength against different damage types',
+ PHRASE_DAMAGE_TAKEN: '% of raw damage taken for different damage types',
+
+ TT_TIME_TO_LOSE_SHIELDS: 'Against sustained fire from all opponent\'s weapons',
HELP_MODIFICATIONS_MENU: 'Click on a number to enter a new value, or drag along the bar for small changes',
@@ -208,7 +215,7 @@ export const terms = {
// Damage types
absolute: 'Absolute',
explosive: 'Explosive',
- kinetic: 'Kinetia',
+ kinetic: 'Kinetic',
thermal: 'Thermal',
// Shield sources
diff --git a/src/less/outfit.less b/src/less/outfit.less
index b97c354c..bccd47f8 100755
--- a/src/less/outfit.less
+++ b/src/less/outfit.less
@@ -190,11 +190,25 @@
});
}
+ &.quarter {
+ width: 25%;
+
+ .tablet({
+ td {
+ line-height: 2em;
+ }
+ });
+
+ .smallTablet({
+ width: 50% !important;
+ });
+ }
+
&.third {
width: 33%;
.smallTablet({
- width: 100% !important;
+ width: 50% !important;
});
}