257 lines
8.9 KiB
JavaScript
257 lines
8.9 KiB
JavaScript
/*
|
|
* Copyright (c) 2017 Wind River Systems, Inc.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
*/
|
|
|
|
var Chart = function(element, options) {
|
|
var self = this;
|
|
var title = options.title;
|
|
var margin = options.margin;
|
|
var series = options.series;
|
|
var x_axis_ticks = options.x_axis_ticks;
|
|
var y_axis_ticks = options.y_axis_ticks;
|
|
var line_chart_width = options.width - margin.left - margin.right;
|
|
var line_chart_height = options.height - margin.top - margin.bottom;
|
|
|
|
//self.drag_move = function(d) {
|
|
// console.log(d3.event.dx);
|
|
//};
|
|
//
|
|
//var drag = d3.behavior.drag()
|
|
// .origin(function(d) { return d; })
|
|
// .on("dragstart", self.drag_move)
|
|
// .on("drag", self.drag_move)
|
|
// .on("dragend", self.drag_move);
|
|
|
|
var x = d3.time.scale().range([0, line_chart_width]);
|
|
var y = d3.scale.linear().range([line_chart_height, 10]);
|
|
|
|
var xAxis = d3.svg.axis().scale(x)
|
|
.orient("bottom").ticks(x_axis_ticks);
|
|
//.tickFormat(formatTime);
|
|
|
|
var yAxis = d3.svg.axis().scale(y)
|
|
.orient("left").ticks(y_axis_ticks).tickFormat(d3.format("d"))
|
|
.tickSubdivide(0);
|
|
|
|
var valueLine = d3.svg.line()
|
|
.x(function(d) { return x(d.x); })
|
|
.y(function(d) { return y(d.y); });
|
|
//.interpolate(basis);
|
|
|
|
var chart = d3.select(element)
|
|
.style("border", "1px solid #ddd")
|
|
.style("padding", "5px")
|
|
.append("svg")
|
|
.attr("width", line_chart_width + margin.left + margin.right)
|
|
.attr("height", line_chart_height + margin.top + margin.bottom)
|
|
.append("g")
|
|
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
|
|
|
|
|
|
var hover = d3.select(element).append("div")
|
|
.attr("class", "hover")
|
|
.style("opacity", 1);
|
|
|
|
self.make_x_axis_grid = function() {
|
|
return d3.svg.axis().scale(x).orient("bottom").ticks(5)
|
|
};
|
|
|
|
self.get_hover_content = function(d) {
|
|
var s = series[d.series_id];
|
|
|
|
return '<p" style="display: block; color: white;">' + s.label + ': '
|
|
+ d.y + '<br>' + d.x.toLocaleString() + '</p>';
|
|
};
|
|
|
|
self.zero_data = function () {
|
|
for (var series_i = 0; series_i < series.length; series_i++) {
|
|
for (tick_i=0; tick_i < series[series_i].data.length; tick_i++) {
|
|
series[series_i].data[tick_i].y = 0;
|
|
}
|
|
}
|
|
};
|
|
|
|
self.initialize = function() {
|
|
// Initial data for series
|
|
// var now = new Date().getTime();
|
|
// for (var series_i = 0; series_i < series.length; series_i++) {
|
|
// for (tick_i=0; tick_i < x_axis_ticks; tick_i++) {
|
|
// series[series_i].data.unshift(
|
|
// {series_id: series_i, id: uuid++,
|
|
// x: (new Date(now - (5000 * tick_i))), y: 0});
|
|
// }
|
|
// }
|
|
|
|
// Add Title
|
|
chart.append("text")
|
|
.attr("class", "title")
|
|
.attr("x", 0 - margin.left)
|
|
.attr("y", 0 - (margin.top / 2))
|
|
.text(title);
|
|
|
|
// Box around the chart
|
|
chart.append("rect")
|
|
.style("stroke", "#ddd")
|
|
.style("stoke-width", "1px")
|
|
.style("fill", "none")
|
|
.attr("x", 0)
|
|
.attr("y", 0)
|
|
.attr("width", line_chart_width)
|
|
.attr("height", line_chart_height);
|
|
|
|
// Add the X Axis Grid Lines
|
|
chart.append("g")
|
|
.attr("class", "grid")
|
|
.attr("transform", "translate(0," + line_chart_height + ")")
|
|
.call(self.make_x_axis_grid()
|
|
.tickSize(-line_chart_height, 0, 0)
|
|
.tickFormat("")
|
|
);
|
|
|
|
// Add the X-Axis
|
|
chart.append("g")
|
|
.attr("class", "x_axis")
|
|
.style("font-size", "12px")
|
|
.style("fill", "#bbb")
|
|
.attr("transform", "translate(0," + line_chart_height + ")")
|
|
.call(xAxis);
|
|
|
|
|
|
// Add the Y-Axis
|
|
chart.append("g")
|
|
.attr("class", "y_axis")
|
|
.style("font-size", "12px")
|
|
.style("fill", "#bbb")
|
|
.call(yAxis);
|
|
|
|
// Add value-lines
|
|
for (var series_i = 0; series_i < series.length; series_i++) {
|
|
chart.append("path").attr("id", "line"+series_i)
|
|
.style("stroke", series[series_i].color)
|
|
.attr("d", valueLine(series[series_i].data));
|
|
}
|
|
|
|
self.zero_data();
|
|
};
|
|
|
|
self.update = function(data) {
|
|
|
|
// Add series data.
|
|
for (var series_i = 0; series_i < series.length; series_i++) {
|
|
data[series_i].sort( function(a, b) {
|
|
if (a.x < b.x) return -1;
|
|
if (a.x > b.x) return 1;
|
|
return 0;
|
|
});
|
|
|
|
data[series_i].forEach(function(d) {
|
|
d.x = new Date(d.x);
|
|
d.y = +d.y;
|
|
});
|
|
|
|
for (var data_i = 0; data_i < data[series_i].length; data_i++) {
|
|
series[series_i].data.unshift(data[series_i][data_i]);
|
|
}
|
|
}
|
|
|
|
// Scale the range of the data.
|
|
x.domain(d3.extent(series[0].data, function(d) { return d.x; }));
|
|
y.domain([0, d3.max(series[0].data, function(d) { return d.y; })]);
|
|
|
|
// Update axises.
|
|
chart.select("g.x_axis").transition().duration(500).call(xAxis);
|
|
chart.select("g.y_axis").transition().duration(500).call(yAxis);
|
|
|
|
chart.select("g.grid").transition().duration(500)
|
|
.call(self.make_x_axis_grid().tickSize(-line_chart_height, 0, 0)
|
|
.tickFormat(""));
|
|
|
|
// Updating lines.
|
|
for (var series_i = series.length-1; series_i >= 0; series_i--) {
|
|
chart.select("#line"+series_i)
|
|
.attr("d", valueLine(series[series_i].data))
|
|
.transition().duration(500).ease("linear")
|
|
.style("stroke", series[series_i].color);
|
|
}
|
|
|
|
// Updating hover dots.
|
|
for (var series_i = 0; series_i < series.length; series_i++) {
|
|
// Update hover dots.
|
|
var dots = chart.selectAll(".dots"+series_i)
|
|
.data(series[series_i].data, function(d) {return d.id; })
|
|
|
|
dots.transition()
|
|
.duration(500)
|
|
.attr("cx", function(d) { return x(d.x); })
|
|
.attr("cy", function(d) { return y(d.y); });
|
|
|
|
// Add new hover dots.
|
|
dots.enter().append("circle").classed("dots"+series_i, true)
|
|
.style("stroke", series[series_i].color)
|
|
.style("fill", series[series_i].color)
|
|
.style("opacity", 1)
|
|
.attr("r", 2)
|
|
.attr("cx", function(d) { return x(d.x); })
|
|
.attr("cy", function(d) { return y(d.y); })
|
|
.on("mouseover", function(d) {
|
|
var matrix = this.getScreenCTM()
|
|
.translate(+this.getAttribute("cx"),
|
|
+this.getAttribute("cy"));
|
|
hover.transition()
|
|
.duration(500)
|
|
.style("opacity", 1)
|
|
.style("background-color", series[d.series_id].color)
|
|
hover.html(self.get_hover_content(d))
|
|
.style("font-size", "11px")
|
|
.style("left", (window.pageXOffset + matrix.e + 10) + "px")
|
|
.style("top", (window.pageYOffset + matrix.f - 35) + "px")
|
|
})
|
|
.on("mouseout", function(d) {
|
|
hover.transition()
|
|
.duration(250)
|
|
.style("opacity", 0);
|
|
});
|
|
|
|
// Delete old hover dots.
|
|
dots.exit()
|
|
.remove();
|
|
}
|
|
|
|
// Delete older series data.
|
|
for (var series_i = 0; series_i < series.length; series_i++) {
|
|
for (var data_i = 0; data_i < data[series_i].length; data_i++) {
|
|
if (series[series_i].data.length > x_axis_ticks) {
|
|
series[series_i].data.pop();
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
self.clear = function() {
|
|
self.zero_data();
|
|
|
|
// Clear scales.
|
|
x.domain(d3.extent(series[0].data, function(d) { return d.x; }));
|
|
y.domain([0, d3.max(series[0].data, function(d) { return d.y; })]);
|
|
|
|
// Update axises.
|
|
chart.select("g.x_axis").transition().duration(500).call(xAxis);
|
|
chart.select("g.y_axis").transition().duration(500).call(yAxis);
|
|
|
|
chart.select("g.grid").transition().duration(500)
|
|
.call(self.make_x_axis_grid().tickSize(-line_chart_height, 0, 0)
|
|
.tickFormat(""));
|
|
|
|
// Clear lines.
|
|
for (var series_i = 0; series_i < series.length; series_i++) {
|
|
chart.select("#line"+series_i).remove();
|
|
chart.append("path").attr("id", "line"+series_i)
|
|
.style("stroke", series[series_i].color)
|
|
.attr("d", valueLine(series[series_i].data));
|
|
}
|
|
}
|
|
};
|