I can explain it. query_range runs an instant query across the range, at the interval you specify. The value at time T is whatever the most recent value was before time T. So you'll see a value at 15 second intervals, being the most recent value available at that time, stepped across the time range you asked for.
To get the raw data via the prometheus API, send a plain "query" with a range vector, rather than "query_range" with an instant vector.
However I don't know if you can do that with Grafana. If you try a range vector query in Explore it's rejected:
But no problem via API:
root@prometheus:~# curl -Ssg 'localhost:9090/api/v1/query?query=node_load1[5m]' | jq .
{
"status": "success",
"data": {
"resultType": "matrix",
"result": [
{
"metric": {
"__name__": "node_load1",
"instance": "nuc1",
"job": "node",
"netbox_type": "device"
},
"values": [
[
1592993705.766,
"1.28"
],
[
1592993765.766,
"0.93"
],
[
1592993825.766,
"0.49"
],
[
1592993885.766,
"1.04"
],
[
1592993945.766,
"1.42"
]
]
},
... etc