diff --git a/media/js/src/editors/NegativeProductionExternalityProducerEditor.jsx b/media/js/src/editors/NegativeProductionExternalityProducerEditor.jsx
new file mode 100644
index 000000000..f22462619
--- /dev/null
+++ b/media/js/src/editors/NegativeProductionExternalityProducerEditor.jsx
@@ -0,0 +1,191 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import RangeEditor from '../form-components/RangeEditor.jsx';
+import { handleFormUpdate } from '../utils.js';
+
+export default class NegativeProductionExternalityProducerEditor extends React.Component {
+ render() {
+ const me = this;
+
+ const modesLeft = [
+ 'Negative Producer Externality',
+ 'Unregulated',
+ 'Welfare',
+ ];
+ const modesRight = [
+ 'Pigouvian Tax',
+ 'Pigouvian Tax (Welfare)',
+ ];
+
+ const radioButtons1 = modesLeft.map((optionTitle, idx) =>
+
+
+
+
+ );
+
+ const radioButtons2 = modesRight.map(function(optionTitle, idx) {
+ const newIdx = idx + modesLeft.length;
+ return (
+
+
+
+
+ );
+ });
+
+ return (
+ <>
+
+
+ {radioButtons1}
+
+
+ {radioButtons2}
+
+
+
+
+ {this.props.displaySliders && (
+ <>
+
+
+
+
+
+
+
+ >
+ )}
+ {(
+ this.props.gFunctionChoice === 2 ||
+ this.props.gFunctionChoice === 3
+ ) && (
+
+ )}
+ {(this.props.gFunctionChoice === 3) && (
+
+ )}
+ {(this.props.gFunctionChoice === 4 || this.props.gFunctionChoice === 5) && (
+
+ )}
+ {(this.props.gFunctionChoice === 6 || this.props.gFunctionChoice === 8) && (
+
+ )}
+ {(this.props.gFunctionChoice === 7 || this.props.gFunctionChoice === 9) && (
+
+ )}
+ {(this.props.gFunctionChoice === 10 || this.props.gFunctionChoice === 11) && (
+
+ )}
+
+ >
+ );
+ }
+}
+
+NegativeProductionExternalityProducerEditor.propTypes = {
+ gType: PropTypes.number.isRequired,
+
+ gA1: PropTypes.number.isRequired,
+ gA2: PropTypes.number.isRequired,
+ gA3: PropTypes.number.isRequired,
+ gA4: PropTypes.number.isRequired,
+ gA5: PropTypes.number,
+ gA6: PropTypes.number,
+
+ gFunctionChoice: PropTypes.number.isRequired,
+ gToggle: PropTypes.bool.isRequired,
+
+ displaySliders: PropTypes.bool.isRequired
+};
diff --git a/media/js/src/graphs/NegativeProductionExternalityProducerGraph.js b/media/js/src/graphs/NegativeProductionExternalityProducerGraph.js
index 75c206e8d..ede105aba 100644
--- a/media/js/src/graphs/NegativeProductionExternalityProducerGraph.js
+++ b/media/js/src/graphs/NegativeProductionExternalityProducerGraph.js
@@ -1,6 +1,67 @@
-import {Graph} from './Graph.js';
+import {Graph, positiveRange} from './Graph.js';
+
+export const defaults = [
+ {
+ gXAxisMax: 1000,
+ gYAxisMax: 2500,
+ gA1: 500,
+ gA2: 2,
+ gA3: 50,
+ gA4: 2,
+ }
+];
export class NegativeProductionExternalityProducerGraph extends Graph {
+ static getGraphPane(gFunctionChoice) {
+ return [
+ {
+ label: 'Unregulated Output q*',
+ color: 'red',
+ value: 500
+ },
+ {
+ label: 'Socially Desirable Output qsoc',
+ color: 'orange',
+ value: 247.5
+ },
+ {
+ label: 'Market Price P*',
+ color: 'red',
+ value: 1500
+ },
+ ];
+ }
+ make() {
+ this.l1 = this.board.create(
+ 'functiongraph',
+ [positiveRange(demandLine), 0, this.options.gXAxisMax], {
+ name: 'Demand',
+ withLabel: true,
+ label: {
+ strokeColor: this.l1Color
+ },
+ strokeWidth: 2,
+ strokeColor: this.l1Color,
+ fixed: true,
+ highlight: false
+ }
+ );
+
+ this.l2 = this.board.create(
+ 'functiongraph',
+ [positiveRange(demandLine), 0, this.options.gXAxisMax], {
+ name: 'Demand',
+ withLabel: true,
+ label: {
+ strokeColor: this.l2Color
+ },
+ strokeWidth: 2,
+ strokeColor: this.l2Color,
+ fixed: true,
+ highlight: false
+ }
+ );
+ }
}
export const mkNegativeProductionExternalityProducer = function(board, options) {