Use CSS to size plots instead of absolute position

This will make things a lot easier to resize and track.  Absolute
positions are tough on other elements.  Have the plot fill the whole
containing element.

Change-Id: I9463c86a723e257bf8c9b083b1a8dcc31a544604
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
Signed-off-by: James Kuszmaul <jabukuszmaul@gmail.com>
diff --git a/frc971/analysis/in_process_plotter.cc b/frc971/analysis/in_process_plotter.cc
index c7a715a..0eaf719 100644
--- a/frc971/analysis/in_process_plotter.cc
+++ b/frc971/analysis/in_process_plotter.cc
@@ -25,6 +25,9 @@
   color_wheel_.push_back(Color(1, 1, 0));
   color_wheel_.push_back(Color(0, 1, 1));
   color_wheel_.push_back(Color(1, 0, 1));
+  color_wheel_.push_back(Color(1, 0.6, 0));
+  color_wheel_.push_back(Color(0.6, 0.3, 0));
+  color_wheel_.push_back(Color(1, 1, 1));
 }
 
 void Plotter::Spin() { event_loop_factory_.Run(); }
diff --git a/frc971/analysis/plot_data_utils.ts b/frc971/analysis/plot_data_utils.ts
index def34ed..5d1f4a0 100644
--- a/frc971/analysis/plot_data_utils.ts
+++ b/frc971/analysis/plot_data_utils.ts
@@ -29,9 +29,6 @@
   plotSelect.add(new Option('Select Plot', invalidSelectValue));
 
   const plotDiv = document.createElement('div');
-  plotDiv.style.position = 'absolute';
-  plotDiv.style.top = '30';
-  plotDiv.style.left = '0';
   parentDiv.appendChild(plotDiv);
 
   conn.addReliableHandler(
@@ -50,12 +47,11 @@
         for (let ii = 0; ii < plotFb.figuresLength(); ++ii) {
           const figure = plotFb.figures(ii);
           const figureDiv = document.createElement('div');
-          figureDiv.style.top = figure.position().top().toString();
-          figureDiv.style.left = figure.position().left().toString();
-          figureDiv.style.position = 'absolute';
+          figureDiv.style.width = figure.position().width().toString() + "px";
+          figureDiv.style.height = figure.position().height().toString() + "px";
+          figureDiv.style.position = 'relative';
           div.appendChild(figureDiv);
-          const plot = new Plot(
-              figureDiv, figure.position().width(), figure.position().height());
+          const plot = new Plot(figureDiv);
 
           if (figure.title()) {
             plot.getAxisLabels().setTitle(figure.title());
diff --git a/frc971/control_loops/drivetrain/down_estimator_plotter.ts b/frc971/control_loops/drivetrain/down_estimator_plotter.ts
index c6e414c..7f5bd58 100644
--- a/frc971/control_loops/drivetrain/down_estimator_plotter.ts
+++ b/frc971/control_loops/drivetrain/down_estimator_plotter.ts
@@ -18,7 +18,7 @@
       '/drivetrain', 'frc971.IMUValuesBatch',
       new ImuMessageHandler(conn.getSchema('frc971.IMUValuesBatch')));
 
-  const accelPlot = aosPlotter.addPlot(element, [0, 0], [width, height]);
+  const accelPlot = aosPlotter.addPlot(element, [width, height]);
   accelPlot.plot.getAxisLabels().setTitle(
       'Estimated Accelerations (x = forward, y = lateral, z = vertical)');
   accelPlot.plot.getAxisLabels().setYLabel('Acceleration (m/s/s)');
@@ -31,7 +31,7 @@
   const accelZ = accelPlot.addMessageLine(status, ['down_estimator', 'accel_z']);
   accelZ.setColor(BLUE);
 
-  const velPlot = aosPlotter.addPlot(element, [0, height], [width, height]);
+  const velPlot = aosPlotter.addPlot(element, [width, height]);
   velPlot.plot.getAxisLabels().setTitle('Raw IMU Integrated Velocity');
   velPlot.plot.getAxisLabels().setYLabel('Velocity (m/s)');
   velPlot.plot.getAxisLabels().setXLabel('Monotonic Reading Time (sec)');
@@ -43,7 +43,7 @@
   const velZ = velPlot.addMessageLine(status, ['down_estimator', 'velocity_z']);
   velZ.setColor(BLUE);
 
-  const gravityPlot = aosPlotter.addPlot(element, [0, height * 2], [width, height]);
+  const gravityPlot = aosPlotter.addPlot(element, [width, height]);
   gravityPlot.plot.getAxisLabels().setTitle('Accelerometer Magnitudes');
   gravityPlot.plot.getAxisLabels().setXLabel('Monotonic Sent Time (sec)');
   gravityPlot.plot.setDefaultYRange([0.95, 1.05]);
@@ -58,7 +58,7 @@
   accelMagnitudeLine.setDrawLine(false);
 
   const orientationPlot =
-      aosPlotter.addPlot(element, [0, height * 3], [width, height]);
+      aosPlotter.addPlot(element, [width, height]);
   orientationPlot.plot.getAxisLabels().setTitle('Orientation');
   orientationPlot.plot.getAxisLabels().setYLabel('Angle (rad)');
 
@@ -75,7 +75,7 @@
   yaw.setColor(BLUE);
   yaw.setLabel('yaw');
 
-  const imuAccelPlot = aosPlotter.addPlot(element, [0, height * 4], [width, height]);
+  const imuAccelPlot = aosPlotter.addPlot(element, [width, height]);
   imuAccelPlot.plot.getAxisLabels().setTitle('Filtered Accelerometer Readings');
   imuAccelPlot.plot.getAxisLabels().setYLabel('Acceleration (g)');
   imuAccelPlot.plot.getAxisLabels().setXLabel('Monotonic Reading Time (sec)');
@@ -113,7 +113,7 @@
   expectedAccelZ.setColor(BLUE);
   expectedAccelZ.setPointSize(0);
 
-  const gyroPlot = aosPlotter.addPlot(element, [0, height * 5], [width, height]);
+  const gyroPlot = aosPlotter.addPlot(element, [width, height]);
   gyroPlot.plot.getAxisLabels().setTitle('Gyro Readings');
   gyroPlot.plot.getAxisLabels().setYLabel('Angular Velocity (rad / sec)');
   gyroPlot.plot.getAxisLabels().setXLabel('Monotonic Reading Time (sec)');
@@ -141,7 +141,7 @@
   const gyroZ = gyroPlot.addMessageLine(imu, ['gyro_z']);
   gyroZ.setColor(BLUE);
 
-  const statePlot = aosPlotter.addPlot(element, [0, height * 6], [width, height / 2]);
+  const statePlot = aosPlotter.addPlot(element, [width, height / 2]);
   statePlot.plot.getAxisLabels().setTitle('IMU State');
   statePlot.plot.getAxisLabels().setXLabel('Monotonic Sent Time (sec)');
 
diff --git a/frc971/control_loops/drivetrain/drivetrain_plotter.ts b/frc971/control_loops/drivetrain/drivetrain_plotter.ts
index f55f965..deb300f 100644
--- a/frc971/control_loops/drivetrain/drivetrain_plotter.ts
+++ b/frc971/control_loops/drivetrain/drivetrain_plotter.ts
@@ -24,12 +24,9 @@
       '/drivetrain', 'frc971.IMUValuesBatch',
       new ImuMessageHandler(conn.getSchema('frc971.IMUValuesBatch')));
 
-  let currentTop = 0;
-
   // Polydrivetrain (teleop control) plots
   const teleopPlot =
-      aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
-  currentTop += DEFAULT_HEIGHT / 2;
+      aosPlotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
   teleopPlot.plot.getAxisLabels().setTitle('Drivetrain Teleop Goals');
   teleopPlot.plot.getAxisLabels().setXLabel(TIME);
   teleopPlot.plot.getAxisLabels().setYLabel('bool, throttle/wheel values');
@@ -44,8 +41,7 @@
 
   // Drivetrain Control Mode
   const modePlot =
-      aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
-  currentTop += DEFAULT_HEIGHT / 2;
+      aosPlotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
   // TODO(james): Actually add enum support.
   modePlot.plot.getAxisLabels().setTitle(
       'Drivetrain Mode [POLYDRIVE, MOTION_PROFILE, ' +
@@ -58,9 +54,7 @@
   controllerType.setDrawLine(false);
 
   // Drivetrain Status estimated relative position
-  const positionPlot = aosPlotter.addPlot(element, [0, currentTop],
-                                         [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
-  currentTop += DEFAULT_HEIGHT;
+  const positionPlot = aosPlotter.addPlot(element);
   positionPlot.plot.getAxisLabels().setTitle("Estimated Relative Position " +
                                              "of the Drivetrain");
   positionPlot.plot.getAxisLabels().setXLabel(TIME);
@@ -83,9 +77,7 @@
   rightEncoder.setColor(CYAN);
 
   // Drivetrain Output Voltage
-  const outputPlot =
-      aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
-  currentTop += DEFAULT_HEIGHT;
+  const outputPlot = aosPlotter.addPlot(element);
   outputPlot.plot.getAxisLabels().setTitle('Drivetrain Output');
   outputPlot.plot.getAxisLabels().setXLabel(TIME);
   outputPlot.plot.getAxisLabels().setYLabel('Voltage (V)');
@@ -96,9 +88,7 @@
   rightVoltage.setColor(GREEN);
 
   // Voltage Errors
-  const voltageErrors =
-      aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
-  currentTop += DEFAULT_HEIGHT;
+  const voltageErrors = aosPlotter.addPlot(element);
   voltageErrors.plot.getAxisLabels().setTitle('Voltage Errors');
   voltageErrors.plot.getAxisLabels().setXLabel(TIME);
   voltageErrors.plot.getAxisLabels().setYLabel('Voltage (V)');
@@ -118,9 +108,7 @@
   ekfRightVoltageError.setColor(CYAN);
 
   // Sundry components of the output voltages
-  const otherVoltages =
-      aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
-  currentTop += DEFAULT_HEIGHT;
+  const otherVoltages = aosPlotter.addPlot(element);
   otherVoltages.plot.getAxisLabels().setTitle('Other Voltage Components');
   otherVoltages.plot.getAxisLabels().setXLabel(TIME);
   otherVoltages.plot.getAxisLabels().setYLabel('Voltage (V)');
@@ -144,9 +132,7 @@
   uncappedRightVoltage.setDrawLine(false);
 
   // Drivetrain Velocities
-  const velocityPlot =
-      aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
-  currentTop += DEFAULT_HEIGHT;
+  const velocityPlot = aosPlotter.addPlot(element);
   velocityPlot.plot.getAxisLabels().setTitle('Velocity Plots');
   velocityPlot.plot.getAxisLabels().setXLabel(TIME);
   velocityPlot.plot.getAxisLabels().setYLabel('Wheel Velocity (m/s)');
@@ -183,9 +169,7 @@
   rightSpeed.setColor(BROWN);
 
   // Drivetrain trajectory and localizer velocities
-  const velocityPlot2 = aosPlotter.addPlot(element, [0, currentTop],
-                                          [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
-  currentTop += DEFAULT_HEIGHT;
+  const velocityPlot2 = aosPlotter.addPlot(element);
   velocityPlot2.plot.getAxisLabels().setTitle(
       "Trajectory and Localizer Velocity Plots");
   velocityPlot2.plot.getAxisLabels().setXLabel(TIME);
@@ -221,8 +205,7 @@
   splineLateralVelocity.setPointSize(0.0);
 
   // Heading
-  const yawPlot = aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
-  currentTop += DEFAULT_HEIGHT;
+  const yawPlot = aosPlotter.addPlot(element);
   yawPlot.plot.getAxisLabels().setTitle('Robot Yaw');
   yawPlot.plot.getAxisLabels().setXLabel(TIME);
   yawPlot.plot.getAxisLabels().setYLabel('Yaw (rad)');
@@ -240,9 +223,7 @@
   downEstimatorYaw.setColor(BLUE);
 
   // Pitch/Roll
-  const orientationPlot =
-      aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
-  currentTop += DEFAULT_HEIGHT;
+  const orientationPlot = aosPlotter.addPlot(element);
   orientationPlot.plot.getAxisLabels().setTitle('Orientation');
   orientationPlot.plot.getAxisLabels().setXLabel(TIME);
   orientationPlot.plot.getAxisLabels().setYLabel('Angle (rad)');
@@ -257,9 +238,7 @@
   pitch.setLabel('pitch');
 
   // Accelerometer/Gravity
-  const accelPlot =
-      aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
-  currentTop += DEFAULT_HEIGHT;
+  const accelPlot = aosPlotter.addPlot(element);
   accelPlot.plot.getAxisLabels().setTitle('Accelerometer Readings');
   accelPlot.plot.getAxisLabels().setYLabel('Acceleration (g)');
   accelPlot.plot.getAxisLabels().setXLabel('Monotonic Reading Time (sec)');
@@ -293,9 +272,7 @@
   accelZ.setDrawLine(false);
 
   // Absolute X Position
-  const xPositionPlot =
-      aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
-  currentTop += DEFAULT_HEIGHT;
+  const xPositionPlot = aosPlotter.addPlot(element);
   xPositionPlot.plot.getAxisLabels().setTitle('X Position');
   xPositionPlot.plot.getAxisLabels().setXLabel(TIME);
   xPositionPlot.plot.getAxisLabels().setYLabel('X Position (m)');
@@ -307,9 +284,7 @@
   splineX.setColor(GREEN);
 
   // Absolute Y Position
-  const yPositionPlot =
-      aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
-  currentTop += DEFAULT_HEIGHT;
+  const yPositionPlot = aosPlotter.addPlot(element);
   yPositionPlot.plot.getAxisLabels().setTitle('Y Position');
   yPositionPlot.plot.getAxisLabels().setXLabel(TIME);
   yPositionPlot.plot.getAxisLabels().setYLabel('Y Position (m)');
@@ -321,9 +296,7 @@
   splineY.setColor(GREEN);
 
   // Gyro
-  const gyroPlot =
-      aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
-  currentTop += DEFAULT_HEIGHT;
+  const gyroPlot = aosPlotter.addPlot(element);
   gyroPlot.plot.getAxisLabels().setTitle('Gyro Readings');
   gyroPlot.plot.getAxisLabels().setYLabel('Angular Velocity (rad / sec)');
   gyroPlot.plot.getAxisLabels().setXLabel('Monotonic Reading Time (sec)');
@@ -353,8 +326,7 @@
 
   // IMU States
   const imuStatePlot =
-      aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
-  currentTop += DEFAULT_HEIGHT / 2;
+      aosPlotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
   imuStatePlot.plot.getAxisLabels().setTitle('IMU State');
   imuStatePlot.plot.getAxisLabels().setXLabel(TIME);
   imuStatePlot.plot.setDefaultYRange([-0.1, 1.1]);
diff --git a/frc971/control_loops/drivetrain/robot_state_plotter.ts b/frc971/control_loops/drivetrain/robot_state_plotter.ts
index 829df25..2ce8001 100644
--- a/frc971/control_loops/drivetrain/robot_state_plotter.ts
+++ b/frc971/control_loops/drivetrain/robot_state_plotter.ts
@@ -18,8 +18,7 @@
 
   // Robot Enabled/Disabled and Mode
   const robotStatePlot =
-      aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
-  currentTop += DEFAULT_HEIGHT / 2;
+      aosPlotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
   robotStatePlot.plot.getAxisLabels().setTitle('Robot State');
   robotStatePlot.plot.getAxisLabels().setXLabel(TIME);
   robotStatePlot.plot.getAxisLabels().setYLabel('bool');
@@ -41,7 +40,7 @@
 
   // Battery Voltage
   const batteryPlot =
-      aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
+      aosPlotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
   currentTop += DEFAULT_HEIGHT / 2;
   batteryPlot.plot.getAxisLabels().setTitle('Battery Voltage');
   batteryPlot.plot.getAxisLabels().setXLabel(TIME);
@@ -51,7 +50,7 @@
 
   // PID of process reading sensors
   const readerPidPlot =
-      aosPlotter.addPlot(element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
+      aosPlotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
   currentTop += DEFAULT_HEIGHT / 2;
   readerPidPlot.plot.getAxisLabels().setTitle("PID of Process Reading Sensors");
   readerPidPlot.plot.getAxisLabels().setXLabel(TIME);
diff --git a/frc971/control_loops/drivetrain/spline_plotter.ts b/frc971/control_loops/drivetrain/spline_plotter.ts
index 028a3fc..c39afd5 100644
--- a/frc971/control_loops/drivetrain/spline_plotter.ts
+++ b/frc971/control_loops/drivetrain/spline_plotter.ts
@@ -25,7 +25,7 @@
 
   // Polydrivetrain (teleop control) plots
   const longitudinalPlot = aosPlotter.addPlot(
-      element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
+      element, [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
   currentTop += DEFAULT_HEIGHT / 2;
   longitudinalPlot.plot.getAxisLabels().setTitle('Longitudinal Distance');
   longitudinalPlot.plot.getAxisLabels().setXLabel(TIME);
@@ -35,7 +35,7 @@
       status, ['trajectory_logging', 'distance_remaining']);
 
   const boolPlot = aosPlotter.addPlot(
-      element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
+      element, [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
   currentTop += DEFAULT_HEIGHT / 2;
   boolPlot.plot.getAxisLabels().setTitle('Bool Flags');
   boolPlot.plot.getAxisLabels().setXLabel(TIME);
@@ -46,8 +46,7 @@
   boolPlot.addMessageLine(status, ['trajectory_logging', 'is_executed'])
       .setColor(BLUE);
 
-  const handlePlot = aosPlotter.addPlot(
-      element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
+  const handlePlot = aosPlotter.addPlot(element);
   currentTop += DEFAULT_HEIGHT;
   handlePlot.plot.getAxisLabels().setTitle('Spline Handles');
   handlePlot.plot.getAxisLabels().setXLabel(TIME);
diff --git a/frc971/wpilib/imu_plotter.ts b/frc971/wpilib/imu_plotter.ts
index af23ed9..0c735eb 100644
--- a/frc971/wpilib/imu_plotter.ts
+++ b/frc971/wpilib/imu_plotter.ts
@@ -10,7 +10,7 @@
   const height = 400;
   const aosPlotter = new AosPlotter(conn);
 
-  const accelPlot = aosPlotter.addPlot(element, [0, 0], [width, height]);
+  const accelPlot = aosPlotter.addPlot(element, [width, height]);
   accelPlot.plot.getAxisLabels().setTitle('Accelerometer Readings');
   accelPlot.plot.getAxisLabels().setYLabel('Acceleration (g)');
   accelPlot.plot.getAxisLabels().setXLabel('Monotonic Reading Time (sec)');
@@ -29,7 +29,7 @@
   const accelZ = accelPlot.addMessageLine(imu, ['accelerometer_z']);
   accelZ.setColor([0, 0, 1]);
 
-  const gyroPlot = aosPlotter.addPlot(element, [0, height], [width, height]);
+  const gyroPlot = aosPlotter.addPlot(element, [width, height]);
   gyroPlot.plot.getAxisLabels().setTitle('Gyro Readings');
   gyroPlot.plot.getAxisLabels().setYLabel('Angular Velocity (rad / sec)');
   gyroPlot.plot.getAxisLabels().setXLabel('Monotonic Reading Time (sec)');
@@ -57,14 +57,14 @@
   const gyroZ = gyroPlot.addMessageLine(imu, ['gyro_z']);
   gyroZ.setColor([0, 0, 1]);
 
-  const tempPlot = aosPlotter.addPlot(element, [0, height * 2], [width, height / 2]);
+  const tempPlot = aosPlotter.addPlot(element, [width, height / 2]);
   tempPlot.plot.getAxisLabels().setTitle('IMU Temperature');
   tempPlot.plot.getAxisLabels().setYLabel('Temperature (deg C)');
   tempPlot.plot.getAxisLabels().setXLabel('Monotonic Reading Time (sec)');
 
   tempPlot.addMessageLine(imu, ['temperature']);
 
-  const statePlot = aosPlotter.addPlot(element, [0, height * 2.5], [width, height / 2]);
+  const statePlot = aosPlotter.addPlot(element, [width, height / 2]);
   statePlot.plot.getAxisLabels().setTitle('IMU State');
   statePlot.plot.getAxisLabels().setXLabel('Monotonic Sent Time (sec)');
   statePlot.plot.setDefaultYRange([-0.1, 1.1]);