Skip to content

Commit 0e18478

Browse files
[#692] Create chart net income per land unit
1 parent 5842ec4 commit 0e18478

File tree

3 files changed

+122
-0
lines changed

3 files changed

+122
-0
lines changed

frontend/src/pages/cases/steps/UnderstandIncomeGap.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
ChartNeededIncomeLevel,
1313
ChartFarmEconomicEfficiency,
1414
ChartRevenueToCostRatio,
15+
ChartNetIncomePerLandUnit,
1516
} from "../visualizations";
1617
import { routePath } from "../../../components/route";
1718

@@ -121,6 +122,10 @@ const UnderstandIncomeGap = ({
121122
<Col span={24}>
122123
<ChartRevenueToCostRatio />
123124
</Col>
125+
126+
<Col span={24}>
127+
<ChartNetIncomePerLandUnit />
128+
</Col>
124129
</Row>
125130
);
126131
};
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import React, { useRef, useMemo, useState } from "react";
2+
import { Card, Row, Col, Space } from "antd";
3+
import { SegmentSelector, VisualCardWrapper } from "../components";
4+
import Chart from "../../../components/chart";
5+
import { CaseVisualState, CurrentCaseState } from "../store";
6+
7+
// What we are showing here:
8+
// How much a farmer earns per land unit.
9+
10+
const colors = { current: "#1b726f", feasible: "#9cc2c1" };
11+
12+
const ChartNetIncomePerLandUnit = () => {
13+
const chartFarmEconomicEfficiencyRef = useRef(null);
14+
const currentCase = CurrentCaseState.useState((s) => s);
15+
const dashboardData = CaseVisualState.useState((s) => s.dashboardData);
16+
17+
const [selectedSegment, setSelectedSegment] = useState(null);
18+
19+
const chartData = useMemo(() => {
20+
const primaryCaseCommodityID = currentCase?.case_commodities?.find(
21+
(cc) => cc?.commodity_type === "focus"
22+
)?.id;
23+
24+
const currentDashboardData = dashboardData.find(
25+
(d) => d.id === selectedSegment
26+
);
27+
28+
const primaryAnswers = currentDashboardData?.answers?.filter(
29+
(a) => a.caseCommodityId === primaryCaseCommodityID
30+
);
31+
32+
const totalIncomeAnswers = primaryAnswers?.filter(
33+
(a) => a?.question?.id === 1
34+
);
35+
const landAnswers = primaryAnswers?.filter((a) => a?.question?.id === 2);
36+
37+
// psudocode
38+
// for values in (current, feasible):
39+
// net_income_land_unit = primary-1/primary-2
40+
41+
const data = ["current", "feasible"].map((it) => {
42+
const totalIncome = totalIncomeAnswers?.find(
43+
(val) => val.name === it
44+
)?.value;
45+
const land = landAnswers?.find((val) => val.name === it)?.value || 0;
46+
const netIncomeLandUnit = totalIncome / land;
47+
48+
return {
49+
name: it,
50+
value: netIncomeLandUnit,
51+
currency: currentCase?.currency,
52+
color: colors[it],
53+
};
54+
});
55+
return data;
56+
}, [currentCase, dashboardData, selectedSegment]);
57+
58+
return (
59+
<Card className="card-visual-wrapper">
60+
<Row gutter={[20, 20]} align="middle">
61+
<Col span={14}>
62+
<VisualCardWrapper
63+
title="Change Indicators"
64+
bordered
65+
exportElementRef={chartFarmEconomicEfficiencyRef}
66+
exportFilename="Farm Economic Efficiency"
67+
>
68+
<Row gutter={[20, 20]}>
69+
<Col span={24}>
70+
<SegmentSelector
71+
selectedSegment={selectedSegment}
72+
setSelectedSegment={setSelectedSegment}
73+
/>
74+
</Col>
75+
<Col span={24}>
76+
<Chart
77+
wrapper={false}
78+
type="BAR"
79+
loading={!chartData.length}
80+
data={chartData}
81+
extra={{ axisTitle: { y: `${currentCase?.currency}` } }}
82+
/>
83+
</Col>
84+
</Row>
85+
</VisualCardWrapper>
86+
</Col>
87+
<Col span={10}>
88+
<Space direction="vertical">
89+
<div className="section-title">
90+
Focus crop net income per land unit
91+
</div>
92+
<div className="section-description">
93+
This metric captures the net profit earned from the crop per unit
94+
of land and is calculated by dividing net income by the cultivated
95+
area. It reflects how well farmers translate land into financial
96+
returns and is influenced by yields, input use, soil health and
97+
management practices. Higher values show profitable and efficient
98+
land use, while lower values signal underperforming plots,
99+
degraded soils or suboptimal agronomy. Monitoring changes in this
100+
indicator helps understand whether land productivity is improving
101+
and whether interventions are resulting in better economic
102+
outcomes.
103+
<br />
104+
<small style={{ color: "#959390" }}>
105+
*“land unit” to automatically change to what user selected e.g.
106+
hectare/acre etc.
107+
</small>
108+
</div>
109+
</Space>
110+
</Col>
111+
</Row>
112+
</Card>
113+
);
114+
};
115+
116+
export default ChartNetIncomePerLandUnit;

frontend/src/pages/cases/visualizations/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ export { default as ChartHouseholdIncomeComposition } from "./ChartHouseholdInco
1515
export { default as ChartNeededIncomeLevel } from "./ChartNeededIncomeLevel";
1616
export { default as ChartFarmEconomicEfficiency } from "./ChartFarmEconomicEfficiency";
1717
export { default as ChartRevenueToCostRatio } from "./ChartRevenueToCostRatio";
18+
export { default as ChartNetIncomePerLandUnit } from "./ChartNetIncomePerLandUnit";

0 commit comments

Comments
 (0)