diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d5f19d8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+node_modules
+package-lock.json
diff --git a/index.html b/index.html
index a1512a7..79ecaf4 100644
--- a/index.html
+++ b/index.html
@@ -2,18 +2,15 @@
- Scatterwind
-
+ Wind Poem
-
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/scatter.coffee b/scatter.coffee
deleted file mode 100644
index 7806627..0000000
--- a/scatter.coffee
+++ /dev/null
@@ -1,66 +0,0 @@
-width = window.innerWidth
-height = window.innerHeight
-padding = 0
-
-svg = d3.select("body")
- .append("svg")
- .attr(
- width: width
- height: height
- class: 'PuRd'
- )
- .on("click", ->
- if !window.confirm "Reload data?"
- return
- dataset = []
- textarea = d3.select("body").append("textarea")
- svg.attr(style: 'display:none')
-
- loadSnmData = (d) ->
- dataset.push [st.windDirection, st.windSpeed, ix] for st, ix in d
- textarea.html JSON.stringify dataset
-
- parseRows = (e, d) ->
- d3.json 'data/smn/' + f.f.trim(), loadSnmData for f in d
-
- d3.csv "data/list.csv", ((d) -> return { f: d.filename }), parseRows
- )
-
-d3.json 'data/windloc.json', (dataset) ->
- xRange = [ d3.min(dataset,(d)->d[0]), d3.max(dataset,(d)->d[0]) ]
- xScale = d3.scale.linear()
- .domain(xRange)
- .range([padding, width-padding * 2])
- yRange = [ d3.min(dataset,(d)->d[1]), d3.max(dataset,(d)->d[1]) ]
- yScale = d3.scale.linear()
- .domain(yRange)
- .range([height-padding, padding])
- zRange = [ d3.min(dataset,(d)->d[2]), d3.max(dataset,(d)->d[2]) ]
-
- dx = width / 2
- dy = height / 2
-
- mult = 2.0 / 57.296 # 1.997
- minima = xRange[1] * 0.5
- multByMin = (amount) -> if amount < minima then 0.0 else 0.003
-
- xRadial = (delta, amount) -> 10*amount * Math.sin(3.14 * mult * delta) #+ Math.random()*0.25) * multByMin(amount)
- yRadial = (delta, amount) -> 10*amount * -Math.cos(3.14 * mult * delta) #+ Math.random()*0.25) * multByMin(amount)
-
- pad = d3.format("05d")
- quantize = d3.scale.quantile().domain(zRange).range(d3.range(9))
-
- svg.append("g")
- .attr(
- id: "circles"
- )
- .selectAll("circle")
- .data(dataset)
- .enter()
- .append("circle")
- .attr(
- cx: (d) -> xRadial(d[0], d[1]) + dx
- cy: (d) -> yRadial(d[0], d[1]) + dy
- class: (d) ->"q" + quantize(d[2]) + "-9"
- r: 1.6
- )
diff --git a/script.coffee b/script.coffee
index f785a6c..1ab62e5 100644
--- a/script.coffee
+++ b/script.coffee
@@ -1,113 +1,63 @@
-w = 500
-h = 300
-padding = 30
-maxNumber = Math.random()*1000
-numDataPoints = 50
-dataset = (([Math.round(Math.random()*maxNumber),Math.round(Math.random()*maxNumber)]) for num in [1..numDataPoints])
-# console.log dataset
+# Function to fetch and parse wind data
+getWindData = ->
+ d3.text 'https://data.geo.admin.ch/ch.meteoschweiz.messwerte-aktuell/VQHA80.csv', (data) ->
+ rows = d3.csv.parseRows(data)
+ header = rows[0].join(';').split(';')
+ stationIndex = header.indexOf('station/time')
+ windDirIndex = header.indexOf('dkl010z0')
+ windSpeedIndex = header.indexOf('fu3010z0')
-xScale = d3.scale.linear()
- .domain([0, d3.max(dataset,(d)->d[0] )])
- .range([padding, w-padding * 2])
+ for row in rows
+ rowData = row.join(';').split(';')
+ if rowData[stationIndex] == 'GVE'
+ windDirection = parseFloat(rowData[windDirIndex])
+ windSpeed = parseFloat(rowData[windSpeedIndex])
+ generatePoem({direction: windDirection, speed: windSpeed})
+ return
+# --- LLM Integration Placeholder ---
+# NOTE: The following section is a placeholder for integrating a custom LLM API.
+# The current implementation uses a static poem as a fallback because free, no-key LLM APIs
+# were not compatible with the sandboxed environment.
+#
+# To use your own LLM:
+# 1. Replace `YOUR_API_ENDPOINT` with your LLM's endpoint URL.
+# 2. Add your API key to the request headers.
+# 3. Uncomment the `generatePoemWithLLM` function and call it from `generatePoem`.
+# 4. Modify the `prompt` and the response handling as needed for your specific API.
-yScale = d3.scale.linear()
- .domain([0, d3.max(dataset, (d)->d[1])])
- .range([h-padding, padding])
-
-xAxis = d3.svg.axis()
- .scale(xScale)
- .orient("bottom")
- .ticks(5)
-
-yAxis = d3.svg.axis()
- .scale(yScale)
- .orient("left")
- .ticks(5)
-
-
-svg = d3.select("body")
- .append("svg")
- .attr(
- width: w
- height: h
- )
-
-svg.append("clipPath")
- .attr("id","chart-area")
- .append("rect")
- .attr(
- x:padding
- y:padding
- width:w-padding*3
- height:h-padding*2
- )
-svg.append("g")
- .attr(
- id:"circles"
- "clip-path":"url(#chart-area)"
- )
- .selectAll("circle")
- .data(dataset)
- .enter()
- .append("circle")
- .attr(
- cx: (d)->xScale(d[0])
- cy: (d)->yScale(d[1])
- r:2 )
-
-svg.append("g")
- .attr(
- class: "x axis"
- transform: "translate(0,#{h-padding})")
- .call(xAxis)
-
-svg.append("g")
- .attr(
- class: "y axis"
- transform: "translate(#{padding},0)")
- .call(yAxis)
-
-
-
-d3.select("p")
- .on("click", ->
- numValues = dataset.length
- maxNumber = Math.random() * 1000
- dataset = (([Math.round(Math.random()*maxNumber),Math.round(Math.random()*maxNumber)]) for num in [1..numValues])
-
- xScale.domain([0, d3.max(dataset,(d)->d[0])])
- yScale.domain([0, d3.max(dataset,(d)->d[1])])
-
- svg.selectAll("circle")
- .data(dataset)
- .transition()
- .duration(1000)
- .each("start", ->
- d3.select(@)
- .attr(
- fill:"magenta"
- r:7
- )
- )
- .attr(
- cx: (d)->xScale(d[0])
- cy: (d)->yScale(d[1]))
- .each("end", ->
- d3.select(@)
- .transition()
- .duration(1000)
- .attr(
- fill:"black"
- r:2
- )
- )
- svg.select(".x.axis")
- .transition()
- .duration(1000)
- .call(xAxis)
- svg.select(".y.axis")
- .transition()
- .duration(1000)
- .call(yAxis)
- )
+# generatePoemWithLLM = (windData) ->
+# apiKey = "YOUR_API_KEY"
+# apiEndpoint = "YOUR_API_ENDPOINT"
+#
+# prompt = "Write a short poem about the wind, with a speed of #{windData.speed} km/h and a direction of #{windData.direction} degrees. Make a reference to Zephyr, the Greek god of the west wind."
+#
+# d3.json(apiEndpoint)
+# .header("Authorization", "Bearer " + apiKey)
+# .post(JSON.stringify({ prompt: prompt }), (err, response) ->
+# if err
+# console.error "LLM API Error:", err
+# displayPoem(staticPoem) # Fallback to static poem on error
+# else
+# displayPoem(response.poem) # Adjust based on your API's response structure
+# )
+
+# Function to generate a poem.
+generatePoem = (windData) ->
+ # To use the LLM integration, comment out the line below and call generatePoemWithLLM(windData) instead.
+ poem = """
+ A gentle breeze, a whispered sigh,
+ From western skies where Zephyr flies.
+ The wind vane turns, a silent guide,
+ As currents drift and softly glide.
+ """
+ displayPoem(poem)
+
+
+# Function to display the poem
+displayPoem = (poem) ->
+ poemContainer = d3.select("#poem-container")
+ poemContainer.html(poem)
+
+# Initial call to fetch the data
+getWindData()
diff --git a/script.js b/script.js
new file mode 100644
index 0000000..d8a6c00
--- /dev/null
+++ b/script.js
@@ -0,0 +1,78 @@
+// Generated by CoffeeScript 2.7.0
+(function() {
+ // Function to fetch and parse wind data
+ var displayPoem, generatePoem, getWindData;
+
+ getWindData = function() {
+ return d3.text('https://data.geo.admin.ch/ch.meteoschweiz.messwerte-aktuell/VQHA80.csv', function(data) {
+ var header, i, len, row, rowData, rows, stationIndex, windDirIndex, windDirection, windSpeed, windSpeedIndex;
+ rows = d3.csv.parseRows(data);
+ header = rows[0].join(';').split(';');
+ stationIndex = header.indexOf('station/time');
+ windDirIndex = header.indexOf('dkl010z0');
+ windSpeedIndex = header.indexOf('fu3010z0');
+ for (i = 0, len = rows.length; i < len; i++) {
+ row = rows[i];
+ rowData = row.join(';').split(';');
+ if (rowData[stationIndex] === 'GVE') {
+ windDirection = parseFloat(rowData[windDirIndex]);
+ windSpeed = parseFloat(rowData[windSpeedIndex]);
+ generatePoem({
+ direction: windDirection,
+ speed: windSpeed
+ });
+ return;
+ }
+ }
+ });
+ };
+
+ // --- LLM Integration Placeholder ---
+ // NOTE: The following section is a placeholder for integrating a custom LLM API.
+ // The current implementation uses a static poem as a fallback because free, no-key LLM APIs
+ // were not compatible with the sandboxed environment.
+
+ // To use your own LLM:
+ // 1. Replace `YOUR_API_ENDPOINT` with your LLM's endpoint URL.
+ // 2. Add your API key to the request headers.
+ // 3. Uncomment the `generatePoemWithLLM` function and call it from `generatePoem`.
+ // 4. Modify the `prompt` and the response handling as needed for your specific API.
+
+ // generatePoemWithLLM = (windData) ->
+ // apiKey = "YOUR_API_KEY"
+ // apiEndpoint = "YOUR_API_ENDPOINT"
+
+ // prompt = "Write a short poem about the wind, with a speed of #{windData.speed} km/h and a direction of #{windData.direction} degrees. Make a reference to Zephyr, the Greek god of the west wind."
+
+ // d3.json(apiEndpoint)
+ // .header("Authorization", "Bearer " + apiKey)
+ // .post(JSON.stringify({ prompt: prompt }), (err, response) ->
+ // if err
+ // console.error "LLM API Error:", err
+ // displayPoem(staticPoem) # Fallback to static poem on error
+ // else
+ // displayPoem(response.poem) # Adjust based on your API's response structure
+ // )
+
+ // Function to generate a poem.
+ generatePoem = function(windData) {
+ var poem;
+ // To use the LLM integration, comment out the line below and call generatePoemWithLLM(windData) instead.
+ poem = `A gentle breeze, a whispered sigh,
+From western skies where Zephyr flies.
+The wind vane turns, a silent guide,
+As currents drift and softly glide.`;
+ return displayPoem(poem);
+ };
+
+ // Function to display the poem
+ displayPoem = function(poem) {
+ var poemContainer;
+ poemContainer = d3.select("#poem-container");
+ return poemContainer.html(poem);
+ };
+
+ // Initial call to fetch the data
+ getWindData();
+
+}).call(this);
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..af109bd
--- /dev/null
+++ b/style.css
@@ -0,0 +1 @@
+/* Placeholder for styles */