JSFiddle - React, Tailwind, and code Playground
by svenhe
HTML
<script src="https://unpkg.com/d3@5/dist/d3.js"></script>
<script src="https://unpkg.com/[email protected]/crossfilter.js"></script>
<link rel="stylesheet" href="https://unpkg.com/dc@3/dc.css">
<script src="https://unpkg.com/dc@3/dc.js"></script>
<script src="https://rawgit.com/crossfilter/reductio/master/reductio.js"></script>
<script src="https://npmcdn.com/universe@latest/universe.js"></script>
<div id="test"></div>
<!-- here's a way to load data from a jsfiddle, to avoid CORS
problems - see http://stackoverflow.com/a/22896088/676195
-->
<pre id="data">
Prec,Recall,System
0.5,0.5,Test
0.7,0.3,Foo
0.95,0.87,Bar
0.1,0.1,Bad
0.2,0.9,Good
</pre>
CSS
pre#data {
display: none;
}
JavaScript
function safe_division(numerator, denominator){
if (!denominator) { // Matches +0, -0, NaN
return 0.0;
}
return numerator/denominator;
}
function generateFmeasureContours(width, height, beta){
//x axis is recall, y axis is precision
var betasquared = beta * beta;
var values = new Array(height * width);
for (var prec = height, k = 0; prec > 0; --prec) {
for (var rec = 0; rec < width; ++rec, ++k) {
var newPrec = prec/height;
var newRec = rec/width;
values[k] = safe_division((1 + betasquared) * (newPrec * newRec), (betasquared * newPrec) + newRec);
}
}
var thresholds = d3.range(0.0, 1.0, 0.05);
var color = d3.scaleLinear()
.domain(d3.extent(thresholds))
.interpolate(d => d3.interpolateRdYlGn)
var contours = d3.contours()
.size([width, height])
.thresholds(thresholds)
(values);
return [contours, color];
}
d3.selection.prototype.moveToFront = function() {
return this.each(function(){
this.parentNode.appendChild(this);
});
};
var chart = dc.scatterPlot("#test");
var experiments = d3.csvParse(d3.select('pre#data').text());
var ndx = crossfilter(experiments),
scatterDim = ndx.dimension(function(d) {return [d.Prec, d.Recall];}),
scatterGroup = scatterDim.group();
chart
.width(808)
.height(768)
.dimension(scatterDim)
.group(scatterGroup)
.xAxisLabel("Recall")
.x(d3.scaleLinear().domain([0,1]))
.yAxisLabel("Precision")
.y(d3.scaleLinear().domain([0,1]))
.on('renderlet', function (chart) {
var innerChart = chart.select('g.brush');
var width = 300, height=300;
//getting the correct width, height
//var innerChartBoundingRect = innerChart.node().getBoundingClientRect();
//var width = innerChartBoundingRect.width, height=innerChartBoundingRect.height;
[contours, color] = generateFmeasureContours(width,height, 1);
innerChart
.selectAll("path")
.data(contours)
.enter()
.append("path")
...