Published
Edited
Jan 11, 2022
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart = {
let svg = d3.select(DOM.svg(width))
.attr('height', height)
.attr('width', width)
.style('font-family', 'sans-serif')
.style('font-size', 12)
let x = d3.scaleLinear()
.domain([d3.min(data, d => d.x), d3.max(data, d => d.x)])
.range([margin.split, width - margin.right])
let y = d3.scaleLinear()
.domain([Math.min(d3.min(data, d => d.y), 16), Math.max(d3.max(data, d => d.y), 36)]).nice()
.range([height - margin.bottom, margin.top])

let xBar = d3.scaleLinear()
.domain([samples/3, 0])
.range([margin.left, margin.split- 10]);
let xAxis = g => g
.attr('transform', `translate(0, ${height - margin.bottom})`)
.call(d3.axisBottom(x).ticks(width / 80).tickSizeOuter(0))
let yAxis = g => g
.attr('transform', `translate(${width - margin.right +5}, 0)`)
.call(d3.axisRight(y))
.call(g => g.select('.domain').remove())

svg.append('text')
.attr('text-anchor', 'start')
.attr('font-weight', 'bold')
.attr('transform', `translate(${width-10}, ${margin.top})rotate(90)`)
.text("Temperature")

svg.append('text')
.attr('x', width - margin.right)
.attr('y', height)
.attr('text-anchor', 'end')
.attr('font-weight', 'bold')
.attr('transform', 'translate(0,-8)')
.text("Timestamp")
svg.append('g')
.attr("class", "xAxis")
.call(xAxis)
svg.append('g')
.attr("class", "yAxis")
.call(yAxis)

svg.append('line')
.attr('class', 'horizontalLine')
.attr('x1', margin.split - 10)
.attr('x2', width - margin.right +5)
.attr('y1', y(center_line))
.attr('y2', y(center_line))
.style('stroke-width', '2')
.style('stroke', "#00ed62")

svg.append('line')
.attr('class', 'horizontalLine')
.attr('x1', margin.split - 10)
.attr('x2', width - margin.right +5)
.attr('y1', y(lower_control_limit))
.attr('y2', y(lower_control_limit))
.style('stroke-width', '1.5')
.style('stroke', "#fd3243")
.style('opacity', 0.4)

svg.append('line')
.attr('class', 'horizontalLine')
.attr('x1', margin.split - 10)
.attr('x2', width - margin.right +5)
.attr('y1', y(upper_control_limit))
.attr('y2', y(upper_control_limit))
.style('stroke-width', '2')
.style('stroke', "#fd3243")
.style('opacity', 0.4)

function colorBar(d) {
if(d.x0 >= upper_control_limit | d.x1 <= lower_control_limit) {
return "#fd3243"
} else if (d.x0 >= upper_control_limit - 1 | d.x1 <= lower_control_limit + 1) {
return "#ffac55"
} else {
return "#00ed62"
}
}

function color(d) {
if(d.y >= upper_control_limit | d.y <= lower_control_limit) {
return "#fd3243"
} else if (d.y >= upper_control_limit - 1 | d.y <= lower_control_limit + 1) {
return "#ffac55"
} else {
return "#00ed62"
}
}
function update() {
data.push({ y: r() * center_line * 0.4 + center_line, x: d3.max(data, d => d.x) + 1 });
x.domain([d3.min(data, d => d.x), d3.max(data, d => d.x)])
y.domain([Math.min(d3.min(data, d => d.y), 16), Math.max(d3.max(data, d => d.y), 36)]).nice()
let dots = svg
.selectAll(".dot")
.data(data)

let dotsEnter = dots
.join("circle")
.attr("class", "dot")
.merge(dots)
.attr("r", 6)
.attr("cx", d => x(d.x))
.attr("cy", d => y(d.y))
.style("fill", d => color(d))

let triangle = svg
.selectAll(".triang")
.data([data[data.length - 1]])

let triangleEnter = triangle
.join("path")
.attr("class", "triang")
.merge(triangle)
.attr('d', d3.symbol().type(d3.symbolTriangle).size(75))
.attr('transform', d => `translate(${ x(d.x) +4 },${ y(d.y) }) rotate(90)`)
.style("fill", d => color(d))

let lines = svg
.selectAll(".line")
.data(data)

let linesEnter = lines
.join("line")
.attr("class", "line")
.merge(lines)
.attr('x1', d => x(d.x))
.attr('x2', d => x(d.x))
.attr('y1', d => y(center_line))
.attr('y2', d => y(d.y))
.style('stroke-width', '1.5')
.style('stroke', d => color(d))
// .style('stroke', d => (d.y >= upper_control_limit | d.y <= lower_control_limit) ? "#fd3243" : "#00ed62" )

let bins = d3.bin()
.value(d => d.y)
.domain(y.domain())
.thresholds(y.ticks(19))
(data)

let bars = svg
.selectAll(".bar")
.data(bins)

let barsEnter = bars
.join("rect")
.attr("class", "bar")
.merge(bars)
.attr('x', d => xBar(d.length))
.attr('width', d => xBar(0) - xBar(d.length))
.attr('y', d => y(d.x1) +1)
.attr('height', d => Math.max(0, y(d.x0) - y(d.x1) -1))
.attr('fill', d => colorBar(d))
// .attr('fill', d => (d.x0 >= upper_control_limit | d.x1 <= lower_control_limit) ? "#fd3243" : "#00ed62" )

svg.selectAll(".xAxis").call(xAxis);
svg.selectAll(".yAxis").call(yAxis);
data.shift();
}

while(true) {
update()
yield Promises.tick(2000, svg.node())
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more