Published
Edited
Jun 15, 2020
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

chart = {
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);
const radius = 3.5;
// marker rectangle in overview
let overviewMarker = {
x: 0,
y: 0,
w: width,
h: height
};
let transform = d3.zoomIdentity;
let zoom = d3
.zoom()
.extent([[0, 0], [width, height]])
.translateExtent([[0, 0], [width, height]])
.scaleExtent([1, 8])
.on("zoom", zoomed);

//Detail View that shows all
const detailview = svg.append("g");
detailview
.append("rect")
.attr("transform", transform)
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height)
.attr("fill", "#ECEFF1");
detailview
.selectAll("circle")
.data(data)
.join("circle")
.attr("fill", "#263238")
.attr("cx", ([x]) => x)
.attr("cy", ([, y]) => y)
.attr("r", radius)
.attr("fill", (d, i) => d3.interpolateCool(i / data.length))
.attr("stroke-width", 1)
.attr("stroke", "#263238");
//Task 2
//Hint: Create a zoomIdentity object and set the translate
//and scale acoording to overviewSize, width, and height values
const overviewTransform = d3.zoomIdentity.scale(1/(height/overviewSize)).translate(-(width - width* (height/overviewSize) + 40),40);
const overview = svg
.append("g")
.clone(detailview, true)
.attr("transform", overviewTransform)
.attr("viewBox", [0, 0, width, height]);
overview
.append("rect")
//Set width, heigth, Fill, StrokeWidth, Stroke Color
//Hint: Append the data points in the overview object
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height)
.attr("fill", "#ECEFF1")
.attr("stroke-width", 5)
.attr("stroke", "#263238");
overview
.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", ([x]) => x)
.attr("cy", ([, y]) => y)
.attr("r", radius)
.attr("fill", (d, i) => d3.interpolateCool(i / data.length))
.attr("stroke-width", 1)
.attr("stroke", "#263238");
function zoomed() {
transform = d3.event.transform;
}

const markerRect = overview
.append("rect")
.datum(overviewMarker)
//Set x, y, width, height and opacity
//Hint: check the difference between datum and data
//Set stroke width, stroke color
.attr("x", 0)
.attr("y", 0)
.attr("width", d => d.w)
.attr("height", d => d.h)
.attr("fill-opacity",0)
.attr("stroke-width", 5)
.attr("stroke", "#ff0000");
function updateMarkerRect() {
overviewMarker.x = transform.invertX(0);
overviewMarker.y = transform.invertY(0);
overviewMarker.w = transform.invertX(width) - overviewMarker.x;
overviewMarker.h = transform.invertY(height) - overviewMarker.y;
markerRect
.attr("x", d => d.x)
.attr("y", d => d.y)
.attr("width", d => d.w)
.attr("height", d => d.h);
}
function updateMarkerDrag(d) {
//Task 3
//Hint: Use the overview and overviewMarkers parameter
//to set a min and Max constrain for the adjustment of the overviewMarker
let newx = 0;
let newy = 0;
if (d3.event.x > width - d.w) {
newx = width - d.w}
else if(d3.event.x < 0) {
newx = 0}
else{
newx = d3.event.x};
if (d3.event.y > height - d.h) {
newy = height - d.h}
else if(d3.event.y < 0) {
newy = 0}
else{
newy = d3.event.y};
d3.select(this)
.attr("x", d.x = newx )
.attr("y", d.y = newy );
//Hint use d3.zoomIdentity to scale and translate. Substitute 1 with the correct values
let t = d3.zoomIdentity.scale(zoomSlider.value).translate(-d.x,-d.y);
detailview.call(zoom.transform, t);
detailview.attr("transform", transform);
}
function startMarkerDrag(d) {
//Task 3
//Change the apearance of the marker when the user
//interact with it
markerRect.attr("stroke-width",10);
}

function endMarkerDrag(d) {
//Task 3
//Return the marker to its static view
markerRect.attr("stroke-width",5);
}

let markerDrag = d3
.drag()
.on("start", startMarkerDrag)
.on("drag", updateMarkerDrag)
.on("end", endMarkerDrag);
markerRect.call(markerDrag);
//Task 1:
//Hint set the slider step, min and max parameters using the zoom parameter
zoomSlider.min = 1;
zoomSlider.max = 8;
zoomSlider.step = 0.1;
zoomSlider.value = 1;
function sliderZoom() {
//Task 1-2:
//Hint task 2: Use the overview and overviewMarkers parameter
//to set a min and Max constrain for the adjustment of the overviewMarker when the slider value changes
//overviewMarker.x= 0;
//overviewMarker.y= 0;
//Hint task 1: use d3.zoomIdentity to scale and translate. Substitute 1 with the real values
let t = d3.zoomIdentity.translate(width/2,height/2).scale(zoomSlider.value).translate(-width/2,-height/2);
detailview.call(zoom.transform, t);
detailview.attr("transform", transform);
updateMarkerRect();
//Hint:First achieve to scale properly the detail view and then show that on the overViewmarker, details can be done later, like center the scaling or add constrains to the overviewMarker.
}
d3.select(zoomSlider)
.on("input", sliderZoom);

return svg.node();
}


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