Skip to content

Commit 9912673

Browse files
committedMar 26, 2025·
Implement Negative Production Externality - Industry graph
Just the first scenario in this graph type so far.
1 parent 57e6b23 commit 9912673

File tree

4 files changed

+98
-18
lines changed

4 files changed

+98
-18
lines changed
 

‎econplayground/main/views.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def get_context_data(self, *args, **kwargs):
151151
},
152152
{
153153
'graph_type': 27,
154-
'image': None,
154+
'image': 'graph_types/graph_27.png',
155155
},
156156
{
157157
'graph_type': 28,

‎media/img/graph_types/graph_27.png

29 KB
Loading

‎media/js/src/editors/NegativeProductionExternalityIndustryEditor.jsx

+1-3
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@ export default class NegativeProductionExternalityIndustryEditor extends React.C
1010
const modesLeft = [
1111
'Negative Industry Externality',
1212
'Unregulated',
13-
'Welfare',
1413
];
1514
const modesRight = [
16-
'Pigouvian Tax',
17-
'Pigouvian Tax (Welfare)',
15+
'Welfare',
1816
];
1917

2018
const radioButtons1 = modesLeft.map((optionTitle, idx) =>

‎media/js/src/graphs/NegativeProductionExternalityIndustryGraph.js

+96-14
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,48 @@ const eq2 = function(a, b, c, d) {
7373
return (a - c) / (b + d);
7474
};
7575

76-
const psurplus2 = function(a, b, c, d) {
77-
return (ep2(a, b, c, d) - c) * eq2(a, b, c, d) / 2;
76+
const sp2 = function(a, b, c, d, f, g) {
77+
return (b * c + a * d + b * f + a * g) / (b + d + g);
7878
};
7979

80-
const emcmarket2 = function(a, b, c, d, f, g) {
81-
return f + g * eq2(a, b, c, d);
80+
const sq2 = function(a, b, c, d, f, g) {
81+
return (a - c - f) / (b + d + g);
8282
};
8383

84-
const extcost2 = function(a, b, c, d, f, g) {
84+
/*const psurplus2 = function(a, b, c, d) {
85+
return (ep2(a, b, c, d) - c) * eq2(a, b, c, d) / 2;
86+
};*/
87+
88+
/*const emcmarket2 = function(a, b, c, d, f, g) {
89+
return f + g * eq2(a, b, c, d);
90+
};*/
91+
92+
/*const extcost2 = function(a, b, c, d, f, g) {
8593
return emcmarket2(a, b, c, d, f, g) * eq2(a, b, c, d) / 2;
94+
};*/
95+
96+
const spoint2 = function(a, b, c, d, f, g) {
97+
return [sq2(a, b, c, d, f, g), sp2(a, b, c, d, f, g)];
98+
};
99+
100+
const shint2 = function(a, b, c, d, f, g) {
101+
return [0, sp2(a, b, c, d, f, g)];
102+
};
103+
104+
const svint2 = function(a, b, c, d, f, g) {
105+
return [sq2(a, b, c, d, f, g), 0];
106+
};
107+
108+
const epoint2 = function(a, b, c, d) {
109+
return [eq2(a, b, c, d), ep2(a, b, c, d)];
110+
};
111+
112+
const ehint2 = function(a, b, c, d) {
113+
return [0, ep2(a, b, c, d)];
114+
};
115+
116+
const evint2 = function(a, b, c, d) {
117+
return [eq2(a, b, c, d), 0];
86118
};
87119

88120

@@ -95,19 +127,19 @@ export class NegativeProductionExternalityIndustryGraph extends Graph {
95127
value: eq2(gA1, gA2, gA3, gA4).toFixed(2)
96128
},
97129
{
98-
label: 'Producer Surplus PS',
99-
color: 'orange',
100-
value: psurplus2(gA1, gA2, gA3, gA4).toFixed(2)
130+
label: 'Unregulated Price P*',
131+
color: 'red',
132+
value: ep2(gA1, gA2, gA3, gA4).toFixed(2)
101133
},
102134
{
103-
label: 'External Total Cost',
104-
color: 'red',
105-
value: extcost2(gA1, gA2, gA3, gA4, gA5, gA6).toFixed(2)
135+
label: 'Socially Desirable Output Q<sup>soc</sup>',
136+
color: 'orange',
137+
value: sq2(gA1, gA2, gA3, gA4, gA5, gA6).toFixed(2)
106138
},
107139
{
108-
label: 'P*',
109-
color: 'red',
110-
value: ep2(gA1, gA2, gA3, gA4).toFixed(2)
140+
label: 'Socially Desirable Price P<sup>soc</sup>',
141+
color: 'orange',
142+
value: sp2(gA1, gA2, gA3, gA4, gA5, gA6).toFixed(2)
111143
},
112144
];
113145
}
@@ -192,6 +224,56 @@ export class NegativeProductionExternalityIndustryGraph extends Graph {
192224
highlight: false
193225
}
194226
);
227+
228+
if (this.options.gShowIntersection) {
229+
const spointEvaluated = spoint2(
230+
this.options.gA1, this.options.gA2, this.options.gA3,
231+
this.options.gA4, this.options.gA5, this.options.gA6);
232+
233+
this.showIntersection(
234+
this.board.create('line', [
235+
shint2(
236+
this.options.gA1, this.options.gA2, this.options.gA3,
237+
this.options.gA4, this.options.gA5, this.options.gA6),
238+
spointEvaluated
239+
], {
240+
visible: false
241+
}),
242+
this.board.create('line', [
243+
svint2(
244+
this.options.gA1, this.options.gA2, this.options.gA3,
245+
this.options.gA4, this.options.gA5, this.options.gA6),
246+
spointEvaluated
247+
], {
248+
visible: false
249+
}),
250+
false, 'Social', null, 'Q<sup>soc</sup>',
251+
false, false, this.l1Color);
252+
253+
const epointEvaluated = epoint2(
254+
this.options.gA1, this.options.gA2, this.options.gA3,
255+
this.options.gA4);
256+
257+
this.showIntersection(
258+
this.board.create('line', [
259+
ehint2(
260+
this.options.gA1, this.options.gA2, this.options.gA3,
261+
this.options.gA4),
262+
epointEvaluated
263+
], {
264+
visible: false
265+
}),
266+
this.board.create('line', [
267+
evint2(
268+
this.options.gA1, this.options.gA2, this.options.gA3,
269+
this.options.gA4),
270+
epointEvaluated
271+
], {
272+
visible: false
273+
}),
274+
false, 'Market', null, 'Q',
275+
false, false, this.l4Color);
276+
}
195277
}
196278
}
197279

0 commit comments

Comments
 (0)