{
const myDiv = html`<div style="width:800px;height:550px;"></div>`;
const XY = iris.map(d => [d.sepal_length, d.petal_length]);
const k = 3;
let clusterCenters = initializeClusterCenters(
k,
XY,
clusterIntitializationMethod
);
let clusters;
const colors = ["steelblue", "chocolate"];
for (let i = 0; i < nIterations; i++) {
clusters = clusterCenters.map(_ => []);
XY.forEach(d => {
const distanceToClusterCenters = clusterCenters.map(c =>
squaredDistance(c, d)
);
clusters[d3.minIndex(distanceToClusterCenters)].push(d);
});
for (let j = 0; j < k; j++)
clusterCenters[j] = updateClusterCenter(clusterCenters[j], clusters[j]);
const data = clusters.map((cluster, i) => {
return {
x: cluster.map(d => d[0]),
y: cluster.map(d => d[1]),
mode: 'markers',
marker: {
size: 4,
color: colors[i]
}
};
});
const layout = {
showlegend: false,
autosize: false,
width: 800,
height: 550,
margin: { t: 50 },
hovermode: 'closest',
xaxis: {
title: 'sepal_length',
showgrid: false,
zeroline: false
},
yaxis: {
title: 'petal_length',
showgrid: false,
zeroline: false
}
};
layout.shapes = clusters.map((cluster, i) => {
const convexHull = d3.polygonHull(cluster);
if (clusterOutlineShape == "polygon") {
const path = d3.line().curve(d3.curveCatmullRomClosed)(convexHull);
return {
type: 'path',
path: path,
fillcolor: 'rgba(128, 128, 128, 0.4)',
line: {
color: "black"
}
};
} else {
const deltaX =
0.6 *
d3.max(convexHull.map(p => Math.abs(p[0] - clusterCenters[i][0])));
const deltaY =
0.6 *
d3.max(convexHull.map(p => Math.abs(p[1] - clusterCenters[i][1])));
return {
type: 'circle',
xref: 'x',
yref: 'y',
x0: clusterCenters[i][0] - deltaX,
y0: clusterCenters[i][1] - deltaY,
x1: clusterCenters[i][0] + deltaX,
y1: clusterCenters[i][1] + deltaY,
fillcolor: 'rgba(128, 128, 128, 0.4)',
line: {
color: 'black'
}
};
}
});
Plotly.newPlot(myDiv, data, layout, { staticPlot: true });
await Promises.delay(1000);
yield myDiv;
}
}