1. save file as json
2. modify html to show all data 3. set black as the background color of appbar
This commit is contained in:
@@ -79,7 +79,8 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
// TRY THIS: Try changing the color here to a specific color (to
|
||||
// Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
|
||||
// change color while the other colors stay the same.
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
backgroundColor:
|
||||
Colors.black, //Theme.of(context).colorScheme.inversePrimary,
|
||||
// Here we take the value from the MyHomePage object that was created by
|
||||
// the App.build method, and use it to set our appbar title.
|
||||
title: Text(widget.title),
|
||||
@@ -163,7 +164,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
await methodChannel.invokeMethod('getExternalDownloadsPath');
|
||||
DateTime now = DateTime.now();
|
||||
String formattedDate = DateFormat('yyyy-MM-dd_HH-mm-ss').format(now);
|
||||
File file = File('$downloadsPath/$formattedDate.txt');
|
||||
File file = File('$downloadsPath/$formattedDate.json');
|
||||
var sink = file.openWrite();
|
||||
sink.write(jsonEncode(mLightSensorEvents));
|
||||
await sink.flush();
|
||||
|
||||
15
test/Sensor_datas/.vscode/launch.json
vendored
Normal file
15
test/Sensor_datas/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Python Debugger: Current File",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
1
test/Sensor_datas/failed_too_fast.json
Normal file
1
test/Sensor_datas/failed_too_fast.json
Normal file
File diff suppressed because one or more lines are too long
1
test/Sensor_datas/standard.json
Normal file
1
test/Sensor_datas/standard.json
Normal file
File diff suppressed because one or more lines are too long
@@ -1,161 +1,259 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>D3.js Multiple Line Chart</title>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Line Charts with D3.js</title>
|
||||
<script src="https://d3js.org/d3.v7.min.js"></script>
|
||||
<style>
|
||||
.line {
|
||||
fill: none;
|
||||
stroke-width: 2px;
|
||||
}
|
||||
.axis-label {
|
||||
font-size: 16px;
|
||||
|
||||
.dot {
|
||||
fill: red;
|
||||
}
|
||||
.legend {
|
||||
font-size: 16px;
|
||||
|
||||
.tooltip {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
width: auto;
|
||||
padding: 5px;
|
||||
font: 12px sans-serif;
|
||||
background: lightsteelblue;
|
||||
border: 0px;
|
||||
border-radius: 8px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.line-lux {
|
||||
stroke: steelblue;
|
||||
}
|
||||
|
||||
.dot-lux {
|
||||
fill: steelblue;
|
||||
}
|
||||
|
||||
.line-lux_fast {
|
||||
stroke: orange;
|
||||
}
|
||||
|
||||
.dot-lux_fast {
|
||||
fill: orange;
|
||||
}
|
||||
|
||||
.line-lux_slow {
|
||||
stroke: green;
|
||||
}
|
||||
|
||||
.dot-lux_slow {
|
||||
fill: green;
|
||||
}
|
||||
|
||||
.line-diff {
|
||||
stroke: purple;
|
||||
}
|
||||
|
||||
.dot-diff {
|
||||
fill: purple;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<input type="file" id="fileInput" />
|
||||
<div id="chart"></div>
|
||||
<h1>Line Charts with D3.js</h1>
|
||||
<input type="file" id="fileInput">
|
||||
<div id="chart"></div>
|
||||
<div id="chart2"></div>
|
||||
|
||||
<script>
|
||||
// Data
|
||||
const sample_data = [
|
||||
{"lux":1263.0,"timestamp":18188401,"lux_fast":1000.0,"lux_slow":900.0},
|
||||
{"lux":1000.0,"timestamp":18188571,"lux_fast":1263.0,"lux_slow":1000.0},
|
||||
{"lux":900.0,"timestamp":18188741,"lux_fast":1262.0,"lux_slow":1263.0}
|
||||
];
|
||||
<script>
|
||||
document.getElementById('fileInput').addEventListener('change', handleFileSelect, false);
|
||||
|
||||
function createChart(data) {
|
||||
d3.select("#chart").select("svg").remove();
|
||||
// Set the dimensions and margins of the graph
|
||||
const margin = {top: 20, right: 80, bottom: 50, left: 60};
|
||||
const width = 600 - margin.left - margin.right;
|
||||
const height = 400 - margin.top - margin.bottom;
|
||||
|
||||
// Append the svg object to the body of the page
|
||||
const svg = d3.select("#chart")
|
||||
.append("svg")
|
||||
.attr("width", width + margin.left + margin.right)
|
||||
.attr("height", height + margin.top + margin.bottom)
|
||||
.append("g")
|
||||
.attr("transform", `translate(${margin.left},${margin.top})`);
|
||||
|
||||
// X scale
|
||||
const x = d3.scaleLinear()
|
||||
.domain(d3.extent(data, d => d.timestamp))
|
||||
.range([0, width]);
|
||||
|
||||
// Y scale
|
||||
const y = d3.scaleLinear()
|
||||
.domain([d3.min(data, d => Math.min(d.lux, d.lux_fast, d.lux_slow)) - 0.5,
|
||||
d3.max(data, d => Math.max(d.lux, d.lux_fast, d.lux_slow)) + 0.5])
|
||||
.range([height, 0]);
|
||||
|
||||
// Add X axis
|
||||
svg.append("g")
|
||||
.attr("transform", `translate(0,${height})`)
|
||||
.call(d3.axisBottom(x));
|
||||
|
||||
// Add Y axis
|
||||
svg.append("g")
|
||||
.call(d3.axisLeft(y));
|
||||
|
||||
// X axis label
|
||||
svg.append("text")
|
||||
.attr("class", "axis-label")
|
||||
.attr("text-anchor", "middle")
|
||||
.attr("x", width / 2)
|
||||
.attr("y", height + margin.bottom - 10)
|
||||
.text("Timestamp");
|
||||
|
||||
// Y axis label
|
||||
svg.append("text")
|
||||
.attr("class", "axis-label")
|
||||
.attr("text-anchor", "middle")
|
||||
.attr("transform", "rotate(-90)")
|
||||
.attr("y", -margin.left + 20)
|
||||
.attr("x", -height / 2)
|
||||
.text("Lux Value");
|
||||
|
||||
// Line generator
|
||||
const line = d3.line()
|
||||
.x(d => x(d.timestamp))
|
||||
.y(d => y(d.lux));
|
||||
|
||||
// Add the lux line
|
||||
svg.append("path")
|
||||
.datum(data)
|
||||
.attr("class", "line")
|
||||
.attr("d", line)
|
||||
.attr("stroke", "blue");
|
||||
|
||||
// Add the lux_fast
|
||||
svg.append("path")
|
||||
.datum(data)
|
||||
.attr("class", "line")
|
||||
.attr("d", d3.line()
|
||||
.x(d => x(d.timestamp))
|
||||
.y(d => y(d.lux_fast)))
|
||||
.attr("stroke", "red");
|
||||
|
||||
// Add the lux_slow line
|
||||
svg.append("path")
|
||||
.datum(data)
|
||||
.attr("class", "line")
|
||||
.attr("d", d3.line()
|
||||
.x(d => x(d.timestamp))
|
||||
.y(d => y(d.lux_slow)))
|
||||
.attr("stroke", "green");
|
||||
|
||||
// Add legend
|
||||
const legend = svg.append("g")
|
||||
.attr("class", "legend")
|
||||
.attr("transform", `translate(${width + 10}, 0)`);
|
||||
|
||||
const legendItems = [
|
||||
{ label: "Lux", color: "blue" },
|
||||
{ label: "Lux Fast", color: "red" },
|
||||
{ label: "Lux Slow", color: "green" }
|
||||
];
|
||||
|
||||
legendItems.forEach((item, index) => {
|
||||
const legendItem = legend.append("g")
|
||||
.attr("transform", `translate(0, ${index * 20})`);
|
||||
|
||||
legendItem.append("rect")
|
||||
.attr("width", 10)
|
||||
.attr("height", 10)
|
||||
.attr("fill", item.color);
|
||||
|
||||
legendItem.append("text")
|
||||
.attr("x", 15)
|
||||
.attr("y", 10)
|
||||
.text(item.label);
|
||||
});
|
||||
function handleFileSelect(event) {
|
||||
const file = event.target.files[0];
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
// File input event listener
|
||||
document.getElementById('fileInput').addEventListener('change', function(e) {
|
||||
const file = e.target.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
const contents = e.target.result;
|
||||
try {
|
||||
const data = JSON.parse(contents);
|
||||
createChart(data);
|
||||
} catch (error) {
|
||||
console.error("Error parsing JSON:", error);
|
||||
alert("Error parsing JSON file. Please make sure it's a valid JSON.");
|
||||
}
|
||||
};
|
||||
reader.readAsText(file);
|
||||
}
|
||||
});
|
||||
createChart(sample_data);
|
||||
</script>
|
||||
const reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
const contents = e.target.result;
|
||||
const data = JSON.parse(contents);
|
||||
drawChart(data);
|
||||
drawChart2(data);
|
||||
};
|
||||
reader.readAsText(file);
|
||||
}
|
||||
|
||||
function drawChart(data) {
|
||||
const margin = { top: 20, right: 30, bottom: 30, left: 40 },
|
||||
width = 800 - margin.left - margin.right,
|
||||
height = 400 - margin.top - margin.bottom;
|
||||
|
||||
d3.select("#chart").html(""); // Clear previous chart if any
|
||||
|
||||
const svg = d3.select("#chart").append("svg")
|
||||
.attr("width", width + margin.left + margin.right)
|
||||
.attr("height", height + margin.top + margin.bottom)
|
||||
.append("g")
|
||||
.attr("transform", `translate(${margin.left},${margin.top})`);
|
||||
|
||||
const x = d3.scaleLinear()
|
||||
.domain(d3.extent(data, d => d.timestamp))
|
||||
.range([0, width]);
|
||||
|
||||
const y = d3.scaleLinear()
|
||||
.domain([0, d3.max(data, d => Math.max(d.lux, d.lux_fast, d.lux_slow))])
|
||||
.nice()
|
||||
.range([height, 0]);
|
||||
|
||||
const lineLux = d3.line()
|
||||
.x(d => x(d.timestamp))
|
||||
.y(d => y(d.lux));
|
||||
|
||||
const lineLuxFast = d3.line()
|
||||
.x(d => x(d.timestamp))
|
||||
.y(d => y(d.lux_fast));
|
||||
|
||||
const lineLuxSlow = d3.line()
|
||||
.x(d => x(d.timestamp))
|
||||
.y(d => y(d.lux_slow));
|
||||
|
||||
svg.append("g")
|
||||
.attr("transform", `translate(0,${height})`)
|
||||
.call(d3.axisBottom(x));
|
||||
|
||||
svg.append("g")
|
||||
.call(d3.axisLeft(y));
|
||||
|
||||
svg.append("path")
|
||||
.datum(data)
|
||||
.attr("class", "line line-lux")
|
||||
.attr("d", lineLux);
|
||||
|
||||
svg.append("path")
|
||||
.datum(data)
|
||||
.attr("class", "line line-lux_fast")
|
||||
.attr("d", lineLuxFast);
|
||||
|
||||
svg.append("path")
|
||||
.datum(data)
|
||||
.attr("class", "line line-lux_slow")
|
||||
.attr("d", lineLuxSlow);
|
||||
|
||||
// Add dots for lux
|
||||
svg.selectAll(".dot-lux")
|
||||
.data(data)
|
||||
.enter().append("circle")
|
||||
.attr("class", "dot dot-lux")
|
||||
.attr("cx", d => x(d.timestamp))
|
||||
.attr("cy", d => y(d.lux))
|
||||
.attr("r", 3)
|
||||
.on("mouseover", function (event, d) {
|
||||
const tooltip = d3.select("body").append("div").attr("class", "tooltip");
|
||||
tooltip.html(`timestamp: ${d.timestamp}<br>lux: ${d.lux}`)
|
||||
.style("left", (event.pageX + 5) + "px")
|
||||
.style("top", (event.pageY - 28) + "px");
|
||||
})
|
||||
.on("mouseout", function () {
|
||||
d3.select(".tooltip").remove();
|
||||
});
|
||||
|
||||
// Add dots for lux_fast
|
||||
svg.selectAll(".dot-lux_fast")
|
||||
.data(data)
|
||||
.enter().append("circle")
|
||||
.attr("class", "dot dot-lux_fast")
|
||||
.attr("cx", d => x(d.timestamp))
|
||||
.attr("cy", d => y(d.lux_fast))
|
||||
.attr("r", 3)
|
||||
.on("mouseover", function (event, d) {
|
||||
const tooltip = d3.select("body").append("div").attr("class", "tooltip");
|
||||
tooltip.html(`timestamp: ${d.timestamp}<br>lux_fast: ${d.lux_fast}`)
|
||||
.style("left", (event.pageX + 5) + "px")
|
||||
.style("top", (event.pageY - 28) + "px");
|
||||
})
|
||||
.on("mouseout", function () {
|
||||
d3.select(".tooltip").remove();
|
||||
});
|
||||
|
||||
// Add dots for lux_slow
|
||||
svg.selectAll(".dot-lux_slow")
|
||||
.data(data)
|
||||
.enter().append("circle")
|
||||
.attr("class", "dot dot-lux_slow")
|
||||
.attr("cx", d => x(d.timestamp))
|
||||
.attr("cy", d => y(d.lux_slow))
|
||||
.attr("r", 3)
|
||||
.on("mouseover", function (event, d) {
|
||||
const tooltip = d3.select("body").append("div").attr("class", "tooltip");
|
||||
tooltip.html(`timestamp: ${d.timestamp}<br>lux_slow: ${d.lux_slow}`)
|
||||
.style("left", (event.pageX + 5) + "px")
|
||||
.style("top", (event.pageY - 28) + "px");
|
||||
})
|
||||
.on("mouseout", function () {
|
||||
d3.select(".tooltip").remove();
|
||||
});
|
||||
}
|
||||
|
||||
function drawChart2(data) {
|
||||
const margin = { top: 20, right: 30, bottom: 30, left: 40 },
|
||||
width = 800 - margin.left - margin.right,
|
||||
height = 400 - margin.top - margin.bottom;
|
||||
|
||||
d3.select("#chart2").html(""); // Clear previous chart if any
|
||||
|
||||
const svg = d3.select("#chart2").append("svg")
|
||||
.attr("width", width + margin.left + margin.right)
|
||||
.attr("height", height + margin.top + margin.bottom)
|
||||
.append("g")
|
||||
.attr("transform", `translate(${margin.left},${margin.top})`);
|
||||
|
||||
const x = d3.scaleLinear()
|
||||
.domain(d3.extent(data, d => d.timestamp))
|
||||
.range([0, width]);
|
||||
|
||||
const y = d3.scaleLinear()
|
||||
.domain([d3.min(data, d => d.lux - d.lux_slow), d3.max(data, d => d.lux - d.lux_slow)])
|
||||
.nice()
|
||||
.range([height, 0]);
|
||||
|
||||
const lineDiff = d3.line()
|
||||
.x(d => x(d.timestamp))
|
||||
.y(d => y(d.lux - d.lux_slow));
|
||||
|
||||
svg.append("g")
|
||||
.attr("transform", `translate(0,${height})`)
|
||||
.call(d3.axisBottom(x));
|
||||
|
||||
svg.append("g")
|
||||
.call(d3.axisLeft(y));
|
||||
|
||||
svg.append("path")
|
||||
.datum(data)
|
||||
.attr("class", "line line-diff")
|
||||
.attr("d", lineDiff);
|
||||
|
||||
// Add dots for lux - lux_slow
|
||||
svg.selectAll(".dot-diff")
|
||||
.data(data)
|
||||
.enter().append("circle")
|
||||
.attr("class", "dot dot-diff")
|
||||
.attr("cx", d => x(d.timestamp))
|
||||
.attr("cy", d => y(d.lux - d.lux_slow))
|
||||
.attr("r", 3)
|
||||
.on("mouseover", function (event, d) {
|
||||
const tooltip = d3.select("body").append("div").attr("class", "tooltip");
|
||||
tooltip.html(`timestamp: ${d.timestamp}<br>lux - lux_slow: ${d.lux - d.lux_slow}`)
|
||||
.style("left", (event.pageX + 5) + "px")
|
||||
.style("top", (event.pageY - 28) + "px");
|
||||
})
|
||||
.on("mouseout", function () {
|
||||
d3.select(".tooltip").remove();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
BIN
test/Sensor_datas/巷子_1/P_20241212_210225.jpg
Normal file
BIN
test/Sensor_datas/巷子_1/P_20241212_210225.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 MiB |
1
test/Sensor_datas/巷子_1/ROG9.txt
Normal file
1
test/Sensor_datas/巷子_1/ROG9.txt
Normal file
File diff suppressed because one or more lines are too long
1
test/Sensor_datas/巷子_1/ZF11.txt
Normal file
1
test/Sensor_datas/巷子_1/ZF11.txt
Normal file
File diff suppressed because one or more lines are too long
1
test/Sensor_datas/巷子_1/ZF12.txt
Normal file
1
test/Sensor_datas/巷子_1/ZF12.txt
Normal file
File diff suppressed because one or more lines are too long
BIN
test/Sensor_datas/巷子_2/P_20241212_210423.jpg
Normal file
BIN
test/Sensor_datas/巷子_2/P_20241212_210423.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 MiB |
1
test/Sensor_datas/巷子_2/ROG9.txt
Normal file
1
test/Sensor_datas/巷子_2/ROG9.txt
Normal file
File diff suppressed because one or more lines are too long
1
test/Sensor_datas/巷子_2/ZF11.txt
Normal file
1
test/Sensor_datas/巷子_2/ZF11.txt
Normal file
File diff suppressed because one or more lines are too long
1
test/Sensor_datas/巷子_2/ZF12.txt
Normal file
1
test/Sensor_datas/巷子_2/ZF12.txt
Normal file
File diff suppressed because one or more lines are too long
BIN
test/Sensor_datas/樓梯_1/P_20241212_205426.jpg
Normal file
BIN
test/Sensor_datas/樓梯_1/P_20241212_205426.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
1
test/Sensor_datas/樓梯_1/ROG9.txt
Normal file
1
test/Sensor_datas/樓梯_1/ROG9.txt
Normal file
File diff suppressed because one or more lines are too long
1
test/Sensor_datas/樓梯_1/ZF11.txt
Normal file
1
test/Sensor_datas/樓梯_1/ZF11.txt
Normal file
File diff suppressed because one or more lines are too long
1
test/Sensor_datas/樓梯_1/ZF12.txt
Normal file
1
test/Sensor_datas/樓梯_1/ZF12.txt
Normal file
File diff suppressed because one or more lines are too long
1
test/Sensor_datas/樓梯_2/ROG9.txt
Normal file
1
test/Sensor_datas/樓梯_2/ROG9.txt
Normal file
File diff suppressed because one or more lines are too long
1
test/Sensor_datas/樓梯_2/ZF11.txt
Normal file
1
test/Sensor_datas/樓梯_2/ZF11.txt
Normal file
File diff suppressed because one or more lines are too long
1
test/Sensor_datas/樓梯_2/ZF12.txt
Normal file
1
test/Sensor_datas/樓梯_2/ZF12.txt
Normal file
File diff suppressed because one or more lines are too long
BIN
test/Sensor_datas/馬路_1/P_20241212_205646.jpg
Normal file
BIN
test/Sensor_datas/馬路_1/P_20241212_205646.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 MiB |
1
test/Sensor_datas/馬路_1/ROG9.txt
Normal file
1
test/Sensor_datas/馬路_1/ROG9.txt
Normal file
File diff suppressed because one or more lines are too long
1
test/Sensor_datas/馬路_1/ZF11.txt
Normal file
1
test/Sensor_datas/馬路_1/ZF11.txt
Normal file
File diff suppressed because one or more lines are too long
1
test/Sensor_datas/馬路_1/ZF12.txt
Normal file
1
test/Sensor_datas/馬路_1/ZF12.txt
Normal file
File diff suppressed because one or more lines are too long
BIN
test/Sensor_datas/馬路_2/P_20241212_205837.jpg
Normal file
BIN
test/Sensor_datas/馬路_2/P_20241212_205837.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 MiB |
1
test/Sensor_datas/馬路_2/ROG9.txt
Normal file
1
test/Sensor_datas/馬路_2/ROG9.txt
Normal file
File diff suppressed because one or more lines are too long
1
test/Sensor_datas/馬路_2/ZF11.txt
Normal file
1
test/Sensor_datas/馬路_2/ZF11.txt
Normal file
File diff suppressed because one or more lines are too long
1
test/Sensor_datas/馬路_2/ZF12.txt
Normal file
1
test/Sensor_datas/馬路_2/ZF12.txt
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user