D3.js使用json格式資料繪出曲線圖(Line Chart)之程式範例
由於工作專案要用D3.js和json格式資料畫出曲線圖(Line Chart),寫出了第一個版本,但現在的專案改寫了第二版,因此將第一版程式碼記錄如下:
//第一版:時間x軸以小時為單位,並且限制資料配合0~24小時的刻度
function GenerateSVGLineChart(SVGName, FacilityID, ParameterID, yScaleTitle, LikeFacilityParameterID) {
// Set the dimensions of the canvas / graph
var svg = d3.select(SVGName),
margin = { top: 30, right: 70, bottom: 80, left: 80 },
width = parseInt(d3.select(".tab-content").style("width")) - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
padding = 20;
// Parse the date / time
var parseDateTime = d3.timeParse("%Y/%m/%d %H:%M");
//定義 x 尺度
var xScale = d3.scaleLinear()
.domain([0, 24])
.nice(d3.timeDay,1)
.range([padding, width - padding * 2]);
var yScale = d3.scaleLinear().range([height, 0]);
// Define the line
var temperatureline = d3.line()
.x(function (d) {
return xScale(d.date);
})
.y(function (d) {
return yScale(d.temperature);
});
// Adds the svg canvas
var svg2 = d3.select(SVGName)
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Get the data
$.ajax({
type: 'POST',
url: '@Url.Action("GetFacilityHistory", "FM")',
data: {
FacilityID: FacilityID,
FacilityParameterID: ParameterID,
LikeFacilityParameterID: LikeFacilityParameterID
},
async: false,
success: function (data) {
var jsonData = data.jsonData;
jsonData.forEach(function (d) {
d.date = parseDateTime(d.ProcessTime).getHours();
d.temperature = +d.FacilityImmediateValue;
});
var xAxis = d3.axisBottom(xScale)
.tickFormat(function (d) {
return d;
});
yScale.domain([0, d3.max(jsonData, function (d) {
return d.temperature;
})]);
// Nest the entries by symbol
var dataNest = d3.nest()
.key(function (d) {
if (FacilityID == null || FacilityID == "") {
//若沒有廠務設備就是篩選出不同的廠務設備
return d.FacilityName;
}
else {
//若有廠務設備就是篩選出不同的參數名稱
return d.FacilityParameterName;
}
})
.entries(jsonData);
// set the colour scale
var color = d3.scaleOrdinal(d3.schemeCategory10);
legendSpace = width / dataNest.length; // spacing for the legend
// Loop through each symbol / key
dataNest.forEach(function (d, i) {
svg2.append("path")
.attr("class", "line")
.style("stroke", function () {
// Add the colours dynamically
return d.color = color(d.key);
})
.attr("d", temperatureline(d.values));
// Add the Legend
svg2.append("text")
.attr("x", (legendSpace / 2) + i * legendSpace) // space legend
.attr("y", height + (margin.bottom / 2) + 5)
.attr("class", "legend") // style the legend
.style("fill", function () { // Add the colours dynamically
return d.color = color(d.key);
})
.text(d.key);
if (FacilityID == null || FacilityID == "") {
//若沒有廠務設備就是篩選出不同的廠務設備
svg2.selectAll(".dottxt")//增加點上的文字
.data(jsonData).enter().append("text")
.attr("class", "dottxt")
.attr("x", function (d) {
return xScale(d.date) - 10;
})
.attr("y", function (d) {
return yScale(d.temperature) - 10;
})
.style("fill", function (d) {
return color(d.FacilityName)
})
.text(function (d) {
return d.temperature;
});
svg2.selectAll("circle")//增加線上的圓點
.data(jsonData).enter().append("circle")
.attr("r", 4)
.attr("cx", function (d) {
return xScale(d.date);
})
.attr("cy", function (d) {
return yScale(d.temperature);
})
.style("fill", function (d) {
return color(d.FacilityName)
})
.append("text")
.attr("class", "dottxt")
.text(d.key)
.style("fill", "#000");
}
else {
//若有廠務設備就是篩選出不同的參數名稱
svg2.selectAll(".dottxt")//增加點上的文字
.data(jsonData).enter().append("text")
.attr("class", "dottxt")
.attr("x", function (d) { return xScale(d.date) - 10; })
.attr("y", function (d) { return yScale(d.temperature) - 10; })
.style("fill", function (d) { return color(d.FacilityParameterName) })
.text(function (d) { return d.FacilityParameterDataName; });
svg2.selectAll("circle")//增加線上的圓點
.data(jsonData).enter().append("circle")
.attr("r", 4)
.attr("cx", function (d) { return xScale(d.date); })
.attr("cy", function (d) { return yScale(d.temperature); })
.style("fill", function (d) { return color(d.FacilityParameterName) })
.append("text")
.attr("class", "dottxt")
.text(d.key)
.style("fill", "#000");
}
});
// Add the X Axis
svg2.append("g")
.attr("class", "axis line-x")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)//d3.axisBottom(xScale)//xAxis
.append("text")
.attr("transform", "rotate(0)")
.attr("x", width / 2)
.attr("y", 30)
.attr("fill", "#000")
.text("時間").style("font-size", "14px");
// Add the Y Axis
svg2.append("g")
.attr("class", "axis line-y")
.call(d3.axisLeft(yScale))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", -46)
.attr("dy", "0.71em")
.attr("fill", "#000")
.text(yScaleTitle).style("font-size", "14px");
}
});
}