diff --git a/scenen/scene02.lua b/scenen/scene02.lua index c8e4ab2..52790ef 100644 --- a/scenen/scene02.lua +++ b/scenen/scene02.lua @@ -99,6 +99,252 @@ function scene:show( event ) print("Cookie:" .. tostring(currentCookie)) + -- Funktion zur Anzeige des Balkendiagramms + local function displayBarChart(dataSets) + -- Entferne alte Diagramm-Anzeigen + for i = sceneGroup.numChildren, 1, -1 do + local child = sceneGroup[i] + if child._isChartDisplay then + child:removeSelf() + end + end + + if not dataSets or type(dataSets) ~= "table" then + print("Keine Daten zum Anzeigen") + return + end + + -- Definiere Farben für die Devices + local deviceColors = { + ["Traun"] = {0.2, 0.4, 0.9}, -- Blau + ["Lannach"] = {0.3, 0.8, 0.4}, -- Grün + ["Sarleinsbach"] = {0.95, 0.6, 0.2} -- Orange + } + + -- Parameter für das Diagramm + local chartX = display.contentCenterX + local chartY = 150 + local chartWidth = display.contentWidth - 40 + local chartHeight = 180 + + -- Hintergrund für das Diagramm + local chartBg = display.newRoundedRect(sceneGroup, chartX, chartY, chartWidth, chartHeight, 8) + chartBg:setFillColor(1, 1, 1) + chartBg.strokeWidth = 2 + chartBg:setStrokeColor(0.7, 0.7, 0.7) + chartBg._isChartDisplay = true + + -- Titel + local titleText = display.newText({ + parent = sceneGroup, + text = "Wochenübersicht (kW)", + x = chartX, + y = chartY - chartHeight/2 - 15, + fontSize = 16, + font = native.systemFontBold + }) + titleText:setFillColor(0.2, 0.2, 0.2) + titleText._isChartDisplay = true + + -- Organisiere Daten nach Tag + local dayData = {} -- { ["2024-05-20"] = { Traun = value, Lannach = value, Sarleinsbach = value } } + local maxValue = 0 + + for deviceName, dataSet in pairs(dataSets) do + if not dataSet.error and type(dataSet) == "table" and #dataSet > 0 then + for _, meter in ipairs(dataSet) do + if meter.values and #meter.values > 0 then + for _, valueData in ipairs(meter.values) do + if valueData.value and valueData.datetime then + local date = valueData.datetime:match("(%d%d%d%d%-%d%d%-%d%d)") + if date then + if not dayData[date] then + dayData[date] = {} + end + dayData[date][deviceName] = valueData.value + maxValue = math.max(maxValue, valueData.value) + end + end + end + break -- Nur das erste Meter pro Device + end + end + end + end + + -- Sortiere Tage + local sortedDays = {} + for day in pairs(dayData) do + table.insert(sortedDays, day) + end + table.sort(sortedDays) + + if #sortedDays == 0 then + local noDataText = display.newText({ + parent = sceneGroup, + text = "Keine Daten zum Anzeigen", + x = chartX, + y = chartY, + fontSize = 14 + }) + noDataText:setFillColor(0.5, 0.5, 0.5) + noDataText._isChartDisplay = true + return + end + + -- Berechne Diagramm-Parameter + local graphLeft = chartX - chartWidth/2 + 30 + local graphRight = chartX + chartWidth/2 - 10 + local graphTop = chartY - chartHeight/2 + 25 + local graphBottom = chartY + chartHeight/2 - 35 + local graphWidth = graphRight - graphLeft + local graphHeight = graphBottom - graphTop + + -- Zeichne Y-Achse + local yAxis = display.newLine(sceneGroup, graphLeft, graphTop, graphLeft, graphBottom) + yAxis:setStrokeColor(0.5, 0.5, 0.5) + yAxis.strokeWidth = 2 + yAxis._isChartDisplay = true + + -- Zeichne X-Achse + local xAxis = display.newLine(sceneGroup, graphLeft, graphBottom, graphRight, graphBottom) + xAxis:setStrokeColor(0.5, 0.5, 0.5) + xAxis.strokeWidth = 2 + xAxis._isChartDisplay = true + + -- Y-Achsen-Beschriftung + local maxLabel = display.newText({ + parent = sceneGroup, + text = string.format("%.0f", maxValue), + x = graphLeft - 15, + y = graphTop, + fontSize = 9 + }) + maxLabel:setFillColor(0.4, 0.4, 0.4) + maxLabel._isChartDisplay = true + + local zeroLabel = display.newText({ + parent = sceneGroup, + text = "0", + x = graphLeft - 15, + y = graphBottom, + fontSize = 9 + }) + zeroLabel:setFillColor(0.4, 0.4, 0.4) + zeroLabel._isChartDisplay = true + + -- Zeichne Balken für jeden Tag + local dayWidth = graphWidth / #sortedDays + local barSpacing = 4 + local barWidth = dayWidth - barSpacing * 2 + + for i, day in ipairs(sortedDays) do + local dayX = graphLeft + (i - 0.5) * dayWidth + local data = dayData[day] + + -- Datum-Label + local dayLabel = display.newText({ + parent = sceneGroup, + text = day:match("%d%d%-%d%d$"), -- Nur MM-DD + x = dayX, + y = graphBottom + 12, + fontSize = 8 + }) + dayLabel:setFillColor(0.3, 0.3, 0.3) + dayLabel._isChartDisplay = true + + -- Berechne Gesamtwert für diesen Tag + local totalValue = 0 + local deviceOrder = {"Traun", "Lannach", "Sarleinsbach"} + for _, deviceName in ipairs(deviceOrder) do + totalValue = totalValue + (data[deviceName] or 0) + end + + if totalValue > 0 then + -- Zeichne gestapelten Balken - prozentual zur vollen Diagrammhöhe + local currentY = graphBottom + + for _, deviceName in ipairs(deviceOrder) do + local value = data[deviceName] or 0 + if value > 0 then + -- Berechne Segment-Höhe proportional zum Anteil am Gesamtwert + -- Balken nutzt die volle Höhe, Segmente sind prozentual + local percentage = value / totalValue + local segmentHeight = percentage * graphHeight + local segmentY = currentY - segmentHeight/2 + + -- Segment + local segment = display.newRect(sceneGroup, dayX, segmentY, barWidth, segmentHeight) + local color = deviceColors[deviceName] or {0.5, 0.5, 0.5} + segment:setFillColor(unpack(color)) + segment.strokeWidth = 1 + segment:setStrokeColor(0.9, 0.9, 0.9) + segment._isChartDisplay = true + + -- Wert-Label im Segment (wenn genug Platz) + if segmentHeight > 12 then + local valueLabel = display.newText({ + parent = sceneGroup, + text = string.format("%d\n%.0f%%", value, percentage * 100), + x = dayX, + y = segmentY, + fontSize = 7, + font = native.systemFontBold + }) + valueLabel:setFillColor(1, 1, 1) + valueLabel._isChartDisplay = true + end + + -- Bewege Y-Position nach oben für nächstes Segment + currentY = currentY - segmentHeight + end + end + + -- Gesamtwert über dem Balken + local totalLabel = display.newText({ + parent = sceneGroup, + text = string.format("%d", totalValue), + x = dayX, + y = graphTop - 8, + fontSize = 8, + font = native.systemFontBold + }) + totalLabel:setFillColor(0.2, 0.2, 0.2) + totalLabel._isChartDisplay = true + end + end + + -- Legende + local legendY = chartY + chartHeight/2 + 20 + local legendDevices = { + {name = "Traun", color = deviceColors["Traun"]}, + {name = "Lannach", color = deviceColors["Lannach"]}, + {name = "Sarleinsbach", color = deviceColors["Sarleinsbach"]} + } + + for i, legend in ipairs(legendDevices) do + local legendX = chartX - 90 + ((i - 1) * 90) + + -- Farbbox + local colorBox = display.newRect(sceneGroup, legendX - 20, legendY, 12, 8) + colorBox:setFillColor(unpack(legend.color)) + colorBox._isChartDisplay = true + + -- Device Name + local legendText = display.newText({ + parent = sceneGroup, + text = legend.name, + x = legendX + 10, + y = legendY, + fontSize = 10 + }) + legendText:setFillColor(0.3, 0.3, 0.3) + legendText._isChartDisplay = true + end + + print("✓ Balkendiagramm erstellt für " .. #sortedDays .. " Tage") + end + -- Funktion zum Neuladen der Daten local function reloadDataFromSevenDays() if not currentCookie or not devices or not selectedDate then @@ -151,7 +397,10 @@ function scene:show( event ) print(json.prettify(currentDataSets)) print("===============================================================\n") -- Zeige neue Daten - print("✓ Daten erfolgreich geladen") + print("✓ Daten erfolgreich geladen") + + -- Zeige Balkendiagramm + displayBarChart(currentDataSets) end end