Fadlhasn commited on
Commit
daf20e7
·
verified ·
1 Parent(s): c04d49d

اجعل هذا الغراف اكثر ديناميكا وتحكم ومعلومات

Browse files
Files changed (3) hide show
  1. math-visualizer.html +16 -2
  2. math-visualizer.js +111 -10
  3. style.css +8 -0
math-visualizer.html CHANGED
@@ -26,10 +26,24 @@
26
  <label class="block text-gray-700 mb-2">Enter function (e.g., sin(x), x^2):</label>
27
  <input type="text" id="functionInput" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent" value="sin(x)">
28
  </div>
29
- <div class="h-64">
30
  <canvas id="functionGraph"></canvas>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  </div>
32
- </div>
33
 
34
  <div class="bg-white p-6 rounded-xl shadow-lg">
35
  <h2 class="text-2xl font-bold text-gray-800 mb-4">Geometry Playground</h2>
 
26
  <label class="block text-gray-700 mb-2">Enter function (e.g., sin(x), x^2):</label>
27
  <input type="text" id="functionInput" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent" value="sin(x)">
28
  </div>
29
+ <div class="h-64 relative">
30
  <canvas id="functionGraph"></canvas>
31
+ <div class="absolute top-4 right-4 flex space-x-2">
32
+ <button id="zoomIn" class="bg-white p-2 rounded-full shadow hover:bg-gray-100">
33
+ <i data-feather="zoom-in"></i>
34
+ </button>
35
+ <button id="zoomOut" class="bg-white p-2 rounded-full shadow hover:bg-gray-100">
36
+ <i data-feather="zoom-out"></i>
37
+ </button>
38
+ <button id="resetView" class="bg-white p-2 rounded-full shadow hover:bg-gray-100">
39
+ <i data-feather="refresh-cw"></i>
40
+ </button>
41
+ </div>
42
+ <div id="coordinatesDisplay" class="absolute bottom-4 left-4 bg-white/80 px-3 py-1 rounded-lg text-sm shadow">
43
+ x: 0, y: 0
44
+ </div>
45
  </div>
46
+ </div>
47
 
48
  <div class="bg-white p-6 rounded-xl shadow-lg">
49
  <h2 class="text-2xl font-bold text-gray-800 mb-4">Geometry Playground</h2>
math-visualizer.js CHANGED
@@ -1,7 +1,8 @@
1
  document.addEventListener('DOMContentLoaded', () => {
2
- // Function Graph Visualization
3
  const functionCtx = document.getElementById('functionGraph').getContext('2d');
4
- const algebraCtx = document.getElementById('algebraGraph').getContext('2d');
 
5
 
6
  // Initialize function graph
7
  const functionGraph = new Chart(functionCtx, {
@@ -18,22 +19,76 @@ document.addEventListener('DOMContentLoaded', () => {
18
  },
19
  options: {
20
  responsive: true,
 
21
  scales: {
22
  x: {
23
  type: 'linear',
24
  position: 'center',
25
- min: -10,
26
- max: 10
 
 
 
 
 
 
 
 
 
 
27
  },
28
  y: {
29
  type: 'linear',
30
  position: 'center',
31
- min: -5,
32
- max: 5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  }
 
 
 
 
34
  }
35
  }
36
- });
37
 
38
  // Initialize algebra graph
39
  const algebraGraph = new Chart(algebraCtx, {
@@ -65,26 +120,72 @@ document.addEventListener('DOMContentLoaded', () => {
65
  }
66
  }
67
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
  // Update function graph when input changes
70
  document.getElementById('functionInput').addEventListener('input', function() {
71
  updateFunctionGraph();
72
  });
73
 
 
 
 
 
 
 
 
 
74
  function updateFunctionGraph() {
75
  const func = document.getElementById('functionInput').value;
76
  const data = [];
 
77
 
78
- for (let x = -10; x <= 10; x += 0.1) {
79
  try {
80
  const y = math.evaluate(func, {x: x});
81
- data.push({x: x, y: y});
 
 
 
 
82
  } catch (e) {
83
  console.error("Error evaluating function:", e);
 
84
  }
85
  }
86
 
87
- functionGraph.data.datasets[0].data = data;
 
 
88
  functionGraph.update();
89
  }
90
 
 
1
  document.addEventListener('DOMContentLoaded', () => {
2
+ // Function Graph Visualization with enhanced controls
3
  const functionCtx = document.getElementById('functionGraph').getContext('2d');
4
+ let xMin = -10, xMax = 10, yMin = -5, yMax = 5;
5
+ const algebraCtx = document.getElementById('algebraGraph').getContext('2d');
6
 
7
  // Initialize function graph
8
  const functionGraph = new Chart(functionCtx, {
 
19
  },
20
  options: {
21
  responsive: true,
22
+ maintainAspectRatio: false,
23
  scales: {
24
  x: {
25
  type: 'linear',
26
  position: 'center',
27
+ min: xMin,
28
+ max: xMax,
29
+ title: {
30
+ display: true,
31
+ text: 'x-axis',
32
+ font: {
33
+ weight: 'bold'
34
+ }
35
+ },
36
+ grid: {
37
+ color: (ctx) => ctx.tick.value === 0 ? '#000' : 'rgba(0, 0, 0, 0.1)'
38
+ }
39
  },
40
  y: {
41
  type: 'linear',
42
  position: 'center',
43
+ min: yMin,
44
+ max: yMax,
45
+ title: {
46
+ display: true,
47
+ text: 'y-axis',
48
+ font: {
49
+ weight: 'bold'
50
+ }
51
+ },
52
+ grid: {
53
+ color: (ctx) => ctx.tick.value === 0 ? '#000' : 'rgba(0, 0, 0, 0.1)'
54
+ }
55
+ }
56
+ },
57
+ plugins: {
58
+ tooltip: {
59
+ mode: 'nearest',
60
+ intersect: false,
61
+ callbacks: {
62
+ label: (context) => {
63
+ return `f(${context.parsed.x.toFixed(2)}) = ${context.parsed.y.toFixed(2)}`;
64
+ }
65
+ }
66
+ },
67
+ legend: {
68
+ display: false
69
+ },
70
+ zoom: {
71
+ pan: {
72
+ enabled: true,
73
+ mode: 'xy'
74
+ },
75
+ zoom: {
76
+ wheel: {
77
+ enabled: true
78
+ },
79
+ pinch: {
80
+ enabled: true
81
+ },
82
+ mode: 'xy'
83
+ }
84
  }
85
+ },
86
+ interaction: {
87
+ mode: 'nearest',
88
+ intersect: false
89
  }
90
  }
91
+ });
92
 
93
  // Initialize algebra graph
94
  const algebraGraph = new Chart(algebraCtx, {
 
120
  }
121
  }
122
  });
123
+ // Add zoom and pan controls
124
+ document.getElementById('zoomIn').addEventListener('click', () => {
125
+ xMin *= 0.8;
126
+ xMax *= 0.8;
127
+ yMin *= 0.8;
128
+ yMax *= 0.8;
129
+ updateGraphScale();
130
+ });
131
+
132
+ document.getElementById('zoomOut').addEventListener('click', () => {
133
+ xMin *= 1.2;
134
+ xMax *= 1.2;
135
+ yMin *= 1.2;
136
+ yMax *= 1.2;
137
+ updateGraphScale();
138
+ });
139
+
140
+ document.getElementById('resetView').addEventListener('click', () => {
141
+ xMin = -10; xMax = 10;
142
+ yMin = -5; yMax = 5;
143
+ updateGraphScale();
144
+ });
145
+
146
+ function updateGraphScale() {
147
+ functionGraph.options.scales.x.min = xMin;
148
+ functionGraph.options.scales.x.max = xMax;
149
+ functionGraph.options.scales.y.min = yMin;
150
+ functionGraph.options.scales.y.max = yMax;
151
+ functionGraph.update();
152
+ }
153
 
154
  // Update function graph when input changes
155
  document.getElementById('functionInput').addEventListener('input', function() {
156
  updateFunctionGraph();
157
  });
158
 
159
+ // Mouse move coordinates display
160
+ const coordDisplay = document.getElementById('coordinatesDisplay');
161
+ document.getElementById('functionGraph').addEventListener('mousemove', (e) => {
162
+ const rect = e.target.getBoundingClientRect();
163
+ const x = xMin + (xMax - xMin) * (e.clientX - rect.left) / rect.width;
164
+ const y = yMax - (yMax - yMin) * (e.clientY - rect.top) / rect.height;
165
+ coordDisplay.textContent = `x: ${x.toFixed(2)}, y: ${y.toFixed(2)}`;
166
+ });
167
  function updateFunctionGraph() {
168
  const func = document.getElementById('functionInput').value;
169
  const data = [];
170
+ let isValid = true;
171
 
172
+ for (let x = xMin; x <= xMax; x += (xMax - xMin)/200) {
173
  try {
174
  const y = math.evaluate(func, {x: x});
175
+ if (!isNaN(y) && isFinite(y)) {
176
+ data.push({x: x, y: y});
177
+ } else {
178
+ isValid = false;
179
+ }
180
  } catch (e) {
181
  console.error("Error evaluating function:", e);
182
+ isValid = false;
183
  }
184
  }
185
 
186
+ // Update line color based on validity
187
+ functionGraph.data.datasets[0].borderColor = isValid ? '#7c3aed' : '#ef4444';
188
+ functionGraph.data.datasets[0].data = data;
189
  functionGraph.update();
190
  }
191
 
style.css CHANGED
@@ -22,6 +22,14 @@ body {
22
  ::-webkit-scrollbar-thumb:hover {
23
  background: #555;
24
  }
 
 
 
 
 
 
 
 
25
 
26
  /* Animation classes */
27
  .fade-in {
 
22
  ::-webkit-scrollbar-thumb:hover {
23
  background: #555;
24
  }
25
+ /* Graph tooltip styles */
26
+ .chartjs-tooltip {
27
+ background: rgba(0, 0, 0, 0.7) !important;
28
+ border-radius: 4px !important;
29
+ color: white !important;
30
+ padding: 8px 12px !important;
31
+ pointer-events: none !important;
32
+ }
33
 
34
  /* Animation classes */
35
  .fade-in {