我正在尝试使用Node Services在WebAPI中生成图表图像,并将其返回给调用它的任何人。我已经设法生成饼图,但是在生成折线图时遇到了困难。我得到以下结果:
JS代码:
// Include all modules we need
const svg2png = require("svg2png");
const { JSDOM } = require("jsdom");
const d3 = require('d3');
// Define module
// callback - function to return data to caller
// options - chart options defined in controller
// data - chart data coming from controller
module.exports = function (callback, options, data) {
// Create disconnected HTML DOM and attach it to D3
var dom = new JSDOM('<html><body><div id="chart"></div></html>');
dom.window.d3 = d3.select(dom.window.document);
var margin = { top: 10, right: 30, bottom: 30, left: 60 },
width = options.width - margin.left - margin.right,
height = options.height - margin.top - margin.bottom;
var svg = dom.window.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 + ")");
var y = d3.scaleLinear()
.rangeRound([height, 0])
.domain(d3.extent(data, function (d) { return d.value; }));
var x = d3.scaleTime()
.rangeRound([0, width])
.domain(d3.extent(data, function (d) { return d.timeStamp; }));
var line = d3.line()
.x(function (d) { return x(d['timeStamp']);
})
.y(function (d) { return y(d['value']); })
.curve(d3.curveMonotoneX);
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.append("text")
.attr("fill", "#000")
.attr("x", 20)
.attr("y", 20)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("Zeitstempel");
svg.append("g")
.call(d3.axisLeft(y))
.append("text")
.attr("fill", "#000")
.attr("x", 0)
.attr("y", -40)
.attr("transform", "rotate(-90)")
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("°C");
svg.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "#FFFFFF")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 1)
.attr("d", line);
// Convert SVG to PNG and return it to controller
var svgText = dom.window.d3.select('#chart').html();
svg2png(Buffer.from(svgText), { width: width, height: height })
.then(buffer => 'data:image/png;base64,' + buffer.toString('base64'))
.then(buffer => callback(null, buffer));
};
C#代码:
[HttpGet("charts/sensorvalues/{id}")]
public async Task<string> GetSensorValueChart(int id)
{
var options = new { width = 360, height = 360 };
var sensorValues = await _repository.GetSensorValueForDeliveryAsync(id);
var data = sensorValues.Select(s => new { value = s.Value, timeStamp = s.TimeStamp });
var chart = await _nodeServices.InvokeAsync<string>("SensorValues.js", options, data);
return chart;
}
y轴正确显示,因为我的最大值约为200,但x轴根本不显示。有人可以帮我吗?
编辑:TimeStamp
是DateTime
值
我知道这有点过时,但是我遇到了同样的问题。我的坐标轴刻度和标签在Y坐标中渲染得离屏幕太远,所以我只是将其退后了。尝试从高度减去边距,或调整平移Y直到看到它出现在图像中:
svg.append("g")
.attr("transform", `translate(0,${height - (margin.top + margin.bottom)})`)
.call(d3.axisBottom(x))
.append("text")
.attr("fill", "#000")
.attr("x", 20)
.attr("y", 20)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("Zeitstempel")