d3-format#format JavaScript Examples
The following examples show how to use
d3-format#format.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: tickFormat.js From cs-wiki with GNU General Public License v3.0 | 6 votes |
export default function tickFormat(start, stop, count, specifier) {
var step = tickStep(start, stop, count),
precision;
specifier = formatSpecifier(specifier == null ? ",f" : specifier);
switch (specifier.type) {
case "s": {
var value = Math.max(Math.abs(start), Math.abs(stop));
if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;
return formatPrefix(specifier, value);
}
case "":
case "e":
case "g":
case "p":
case "r": {
if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
break;
}
case "f":
case "%": {
if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
break;
}
}
return format(specifier);
}
Example #2
Source File: tickFormat.js From cs-wiki with GNU General Public License v3.0 | 6 votes |
export default function(start, stop, count, specifier) {
var step = tickStep(start, stop, count),
precision;
specifier = formatSpecifier(specifier == null ? ",f" : specifier);
switch (specifier.type) {
case "s": {
var value = Math.max(Math.abs(start), Math.abs(stop));
if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;
return formatPrefix(specifier, value);
}
case "":
case "e":
case "g":
case "p":
case "r": {
if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
break;
}
case "f":
case "%": {
if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
break;
}
}
return format(specifier);
}
Example #3
Source File: TestTabs.js From likelihood with MIT License | 6 votes |
ScorePanel = React.memo(({derivMuNull, deriv2MuNull, eqChisq}) => {
const classes = useStyles()
const score = (derivMuNull * derivMuNull) / -deriv2MuNull;
const eqScore = katex.renderToString(
`
\\begin{aligned}
S(\\mu_0, \\hat\\sigma_0^2) =& \\frac{U(\\mu_0, \\hat\\sigma_0^2)^2}{I(\\mu_0, \\hat\\sigma_0^2)} \\\\
&= \\frac{${f2n(derivMuNull)}^2}{${f2n(-deriv2MuNull)}} \\\\
&= ${f3n(score)}
\\end{aligned}
`,
{
displayMode: true,
throwOnError: false
}
);
const pvalScore = 1 - chisquare.cdf(score, 1);
return (
<TabPanel className={classes.panel}>
<Typography variant="body1">
The Score test (also known as the Lagrange multiplier test) is
slightly different in the sense that we only evaluate it at the null.
It involves both the first and second derivative evaluated at the
null.
</Typography>
<Typography
variant="body1"
dangerouslySetInnerHTML={{ __html: eqScore }}
/>
<Typography variant="body1">
Asymptotically <em>S</em> follows a{" "}
<span dangerouslySetInnerHTML={{ __html: eqChisq }} /> distribution
with 1 degrees of freedom, which gives <em>p</em> ={" "}
{format(".2f")(pvalScore)}.
</Typography>
</TabPanel>
)
})
Example #4
Source File: tickFormat.js From gamedesign with GNU General Public License v3.0 | 6 votes |
export default function(domain, count, specifier) {
var start = domain[0],
stop = domain[domain.length - 1],
step = tickStep(start, stop, count == null ? 10 : count),
precision;
specifier = formatSpecifier(specifier == null ? ",f" : specifier);
switch (specifier.type) {
case "s": {
var value = Math.max(Math.abs(start), Math.abs(stop));
if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;
return formatPrefix(specifier, value);
}
case "":
case "e":
case "g":
case "p":
case "r": {
if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
break;
}
case "f":
case "%": {
if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
break;
}
}
return format(specifier);
}
Example #5
Source File: format.js From here-covid-19-tracker with MIT License | 5 votes |
formatThousand = num => {
return format(",.8r")(num).split(".")[0]
}
Example #6
Source File: SurveillancePlot.js From covidcg with MIT License | 5 votes |
countsFormatter = format('.2s')
Example #7
Source File: MutationList.js From covidcg with MIT License | 5 votes |
countsFormatter = format('.0%')
Example #8
Source File: TestTabs.js From likelihood with MIT License | 5 votes |
LrtPanel = React.memo(({sigma, sigma0, n, eqChisq}) => {
const classes = useStyles()
const calcLR = (sigma, sigma0, n) => {
const W = Math.pow((sigma0 * sigma0) / (sigma * sigma), -n / 2);
return -2 * Math.log(W);
};
const LR = calcLR(sigma, sigma0, n);
const LRFormat = format(".3n")(LR);
const eqLogLik = katex.renderToString(
`\\begin{aligned}
\\text{LR} &= -2[\\ell(\\mu_{0}, \\hat\\sigma^2_{0}) - [\\ell(\\hat\\mu, \\hat\\sigma^2)]\\\\
&= ${LRFormat}
\\end{aligned}`,
{
displayMode: true,
throwOnError: false
}
);
const pvalLRT = format(".2f")(1 - chisquare.cdf(LR, 1));
return (
<TabPanel className={classes.panel}>
<Typography variant="body1">
The likelihood ratio test compares the likelihood ratios of two
models. In this example {"it's"} the likelihood evaluated at the MLE and
at the null. This is illustrated in the plot by the vertical
distance between the two horizontal lines. If we multiply the
difference in log-likelihood by -2 we get the statistic,
</Typography>
<Typography
variant="body1"
dangerouslySetInnerHTML={{ __html: eqLogLik }}
/>
<Typography variant="body1">
Asymptotically LR follows a{" "}
<span dangerouslySetInnerHTML={{ __html: eqChisq }} /> distribution
with 1 degrees of freedom, which gives <em>p</em> = {pvalLRT}.
</Typography>
<Typography variant="body1">
Note: The figure is simplified and does not account for the fact that
each likelihood is based on different variance estimates.
</Typography>
</TabPanel>
)
})
Example #9
Source File: TestTabs.js From likelihood with MIT License | 5 votes |
WaldPanel = React.memo(({sigma, muHat, muNull, n}) => {
const classes = useStyles();
const se = sigma / Math.sqrt(n);
const waldZ = (muHat - muNull) / se;
const pvalZ = 2 * (1 - normal.cdf(Math.abs(waldZ), 0, 1));
const eqSE = katex.renderToString(
`\\text{se}(\\hat\\mu) = I(\\hat\\mu, \\hat\\sigma^2)^{-1/2}`,
{
displayMode: false,
throwOnError: false
}
)
const eqWald = katex.renderToString(`
\\begin{aligned}
Z =& \\frac{\\hat\\mu - \\mu_0}{\\text{se}(\\hat\\mu)} \\\\
=& \\frac{${f3n(muHat)} - ${f3n(muNull)}}{${f3n(se)}} \\\\
=& ${f3n(waldZ)}
\\end{aligned}
`, {
displayMode: true,
throwOnError: false
})
return (
<TabPanel className={classes.panel}>
<Typography variant="body1">
The Wald test is based on the difference between the maximum
likelihood estimate of the mean and μ0 divided by the standard error
of the MLE, <span dangerouslySetInnerHTML={{ __html: eqSE }} />
</Typography>
<Typography
variant="body1"
dangerouslySetInnerHTML={{ __html: eqWald }}
/>
<Typography variant="body1">
Asymptotically <em>Z</em> follows a standard normal distribution,
giving <em>p</em> = {format(".2f")(pvalZ)}.
</Typography>
</TabPanel>
)
})
Example #10
Source File: TestTabs.js From likelihood with MIT License | 5 votes |
f3n = format(".3n")
Example #11
Source File: TestTabs.js From likelihood with MIT License | 5 votes |
f2n = format(".2n")
Example #12
Source File: CalcLogLik.js From likelihood with MIT License | 5 votes |
CalcLogLik = ({ sample, mu, sigma, highlight, setHighlight }) => {
const classes = useStyles();
const ll = sample.map(x => logLik(x, mu, sigma));
const llSum = ll.reduce((a, b) => a + b, 0);
const eqLogLik = katex.renderToString(
"\\ell(\\mu, \\sigma^2) = \\sum_i^n \\text{ln} \\thinspace f_y(y_i)=",
{
displayMode: false,
throwOnError: false
}
);
return (
<div>
<Typography variant="body1" gutterBottom>
<span dangerouslySetInnerHTML={{ __html: eqLogLik }} />
{ll.map((y, i) => {
y = format(".1f")(y);
return (
<span key={i}>
<span
className={clsx(
classes.logLikSpan,
highlight == i && "highlight"
)}
onMouseOver={() => setHighlight(i)}
onMouseOut={() => setHighlight()}
id={"logLikSpan" + i}
>
{y}
</span>
{i != sample.length - 1 && <span>+</span>}
</span>
);
})}
=
<span className={clsx(classes.logLikSpan, "sum")}>
{format(".1f")(llSum)}
</span>
</Typography>
</div>
);
}
Example #13
Source File: horizontal-bar-chart.js From website with Apache License 2.0 | 5 votes |
HorizontalBarChart = ({
data,
fill,
height,
marginBottom = 0,
marginLeft = 0,
marginRight = 0,
marginTop = 0,
xTicks,
width,
xMax = null,
}) => {
const totalXMargin = marginLeft + marginRight
const totalYMargin = marginTop + marginBottom
const yScale = scaleBand()
.domain(data.map(d => d.name))
.range([0, height - totalYMargin])
.padding(0.2)
const formatTick = format('~s')
const xScale = scaleLinear()
.domain([120, xMax || max(data, d => d.value)])
.nice()
.range([0, width - totalXMargin])
return (
<svg
className={chartStyles.chart}
viewBox={`0 0 ${width} ${height}`}
aria-hidden
>
<g transform={`translate(${marginLeft} ${marginTop})`}>
{xScale.ticks(xTicks).map(tick => (
<g key={tick}>
<text
className={`${chartStyles.label} ${chartStyles.xTickLabel}`}
x={xScale(tick)}
y={height - marginBottom}
>
{formatTick(tick)}
</text>
<line
className={chartStyles.gridLine}
x1={xScale(tick)}
x2={xScale(tick)}
y1={0}
y2={height - totalYMargin}
/>
</g>
))}
</g>
<g transform={`translate(0, ${marginTop})`}>
{data.map(d => (
/* Do not remove nested svg. See https://github.com/COVID19Tracking/website/pull/645#discussion_r411676987 */
<svg
y={yScale(d.name) + 20}
x={marginLeft - 10}
className={chartStyles.yTickLabel}
key={d.name}
>
<text className={chartStyles.label}>{`${d.name}`}</text>
</svg>
))}
</g>
<g transform={`translate(${marginLeft}, ${marginTop})`}>
{data.map(d => (
<rect
key={d.name}
x={0}
y={yScale(d.name)}
height={yScale.bandwidth()}
width={xScale(d.value)}
fill={fill}
/>
))}
</g>
</svg>
)
}
Example #14
Source File: visualization.js From website with Apache License 2.0 | 5 votes |
formatNumber = format(',.0f')
Example #15
Source File: test.legendsymbol.js From t-viSNE with MIT License | 5 votes |
describe('d3-legend #legendSymbol', function() {
it('exports a function', function() {
expect(symbol).to.be.a('function');
});
it('should have a locale', function () {
let result = symbol();
expect(result.locale).to.be.a('function');
});
it('should redefine label\'s format with a string', function () {
let result = symbol();
let testValue = 1.00;
let initial = result.labelFormat();
result.labelFormat('.2f');
expect(initial(testValue)).to.be.not.equal(result.labelFormat()(testValue));
expect(result.labelFormat()(testValue)).to.be.equal('1.00');
});
it('should redefine label\'s format with a format function', function () {
let result = symbol();
let testValue = 1.00;
let initial = result.labelFormat();
result.labelFormat(format('.2f'));
expect(initial(testValue)).to.be.not.equal(result.labelFormat()(testValue));
expect(result.labelFormat()(testValue)).to.be.equal('1.00');
});
it('should redefine the locale with a new locale definition', function () {
let result = symbol();
let testValue = 1.00;
let initial = result.labelFormat();
let frFr = {
decimal: ',',
thousands: '.',
grouping: [3],
currency: ['', '\u00a0€'],
percent: "\u202f%"
};
result.locale(frFr)
expect(initial(testValue)).to.be.not.equal(result.labelFormat()(testValue));
expect(result.labelFormat()(testValue)).to.be.equal('1,0')
})
it('should keep the format specifier after a locale update', function () {
let result = symbol();
let testValue = 1.00;
let initial = result.labelFormat();
let frFr = {
decimal: ',',
thousands: '.',
grouping: [3],
currency: ['', '\u00a0€'],
percent: "\u202f%"
};
result.labelFormat(format('.2f'));
result.locale(frFr)
expect(initial(testValue)).to.be.not.equal(result.labelFormat()(testValue));
expect(result.labelFormat()(testValue)).to.be.equal('1,00')
})
});
Example #16
Source File: test.legendsize.js From t-viSNE with MIT License | 5 votes |
describe('d3-legend #legendSize', function() {
it('exports a function', function() {
expect(size).to.be.a('function');
});
it('should have a locale', function () {
let result = size();
expect(result.locale).to.be.a('function');
});
it('should redefine label\'s format with a string', function () {
let result = size();
let testValue = 1.00;
let initial = result.labelFormat();
result.labelFormat('.2f');
expect(initial(testValue)).to.be.not.equal(result.labelFormat()(testValue));
expect(result.labelFormat()(testValue)).to.be.equal('1.00');
});
it('should redefine label\'s format with a format function', function () {
let result = size();
let testValue = 1.00;
let initial = result.labelFormat();
result.labelFormat(format('.2f'));
expect(initial(testValue)).to.be.not.equal(result.labelFormat()(testValue));
expect(result.labelFormat()(testValue)).to.be.equal('1.00');
});
it('should redefine the locale with a new locale definition', function () {
let result = size();
let testValue = 1.00;
let initial = result.labelFormat();
let frFr = {
decimal: ',',
thousands: '.',
grouping: [3],
currency: ['', '\u00a0€'],
percent: "\u202f%"
};
result.locale(frFr)
expect(initial(testValue)).to.be.not.equal(result.labelFormat()(testValue));
expect(result.labelFormat()(testValue)).to.be.equal('1,0')
})
it('should keep the format specifier after a locale update', function () {
let result = size();
let testValue = 1.00;
let initial = result.labelFormat();
let frFr = {
decimal: ',',
thousands: '.',
grouping: [3],
currency: ['', '\u00a0€'],
percent: "\u202f%"
};
result.labelFormat(format('.2f'));
result.locale(frFr)
expect(initial(testValue)).to.be.not.equal(result.labelFormat()(testValue));
expect(result.labelFormat()(testValue)).to.be.equal('1,00')
})
});
Example #17
Source File: indexRollupNext.js From t-viSNE with MIT License | 4 votes |
helper = {
d3_drawShapes: function d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, path) {
if (shape === "rect") {
shapes.attr("height", shapeHeight).attr("width", shapeWidth);
} else if (shape === "circle") {
shapes.attr("r", shapeRadius);
} else if (shape === "line") {
shapes.attr("x1", 0).attr("x2", shapeWidth).attr("y1", 0).attr("y2", 0);
} else if (shape === "path") {
shapes.attr("d", path);
}
},
d3_addText: function d3_addText(svg, enter, labels, classPrefix, labelWidth) {
enter.append("text").attr("class", classPrefix + "label");
var text = svg.selectAll('g.' + classPrefix + 'cell text.' + classPrefix + 'label').data(labels).text(d3_identity);
if (labelWidth) {
svg.selectAll('g.' + classPrefix + 'cell text.' + classPrefix + 'label').call(d3_textWrapping, labelWidth);
}
return text;
},
d3_calcType: function d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter) {
var type = scale.invertExtent ? d3_quantLegend(scale, labelFormat, labelDelimiter) : scale.ticks ? d3_linearLegend(scale, cells, labelFormat) : d3_ordinalLegend(scale);
//for d3.scaleSequential that doesn't have a range function
var range = scale.range && scale.range() || scale.domain();
type.labels = d3_mergeLabels(type.labels, labels, scale.domain(), range);
if (ascending) {
type.labels = d3_reverse(type.labels);
type.data = d3_reverse(type.data);
}
return type;
},
d3_filterCells: function d3_filterCells(type, cellFilter) {
var filterCells = type.data.map(function (d, i) {
return { data: d, label: type.labels[i] };
}).filter(cellFilter);
var dataValues = filterCells.map(function (d) {
return d.data;
});
var labelValues = filterCells.map(function (d) {
return d.label;
});
type.data = type.data.filter(function (d) {
return dataValues.indexOf(d) !== -1;
});
type.labels = type.labels.filter(function (d) {
return labelValues.indexOf(d) !== -1;
});
return type;
},
d3_placement: function d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign) {
cell.attr("transform", cellTrans);
text.attr("transform", textTrans);
if (orient === "horizontal") {
text.style("text-anchor", labelAlign);
}
},
d3_addEvents: function d3_addEvents(cells, dispatcher) {
cells.on("mouseover.legend", function (d) {
d3_cellOver(dispatcher, d, this);
}).on("mouseout.legend", function (d) {
d3_cellOut(dispatcher, d, this);
}).on("click.legend", function (d) {
d3_cellClick(dispatcher, d, this);
});
},
d3_title: function d3_title(svg, title, classPrefix, titleWidth) {
if (title !== "") {
var titleText = svg.selectAll('text.' + classPrefix + 'legendTitle');
titleText.data([title]).enter().append('text').attr('class', classPrefix + 'legendTitle');
svg.selectAll('text.' + classPrefix + 'legendTitle').text(title);
if (titleWidth) {
svg.selectAll('text.' + classPrefix + 'legendTitle').call(d3_textWrapping, titleWidth);
}
var cellsSvg = svg.select('.' + classPrefix + 'legendCells');
var yOffset = svg.select('.' + classPrefix + 'legendTitle').nodes().map(function (d) {
return d.getBBox().height;
})[0],
xOffset = -cellsSvg.nodes().map(function (d) {
return d.getBBox().x;
})[0];
cellsSvg.attr('transform', 'translate(' + xOffset + ',' + yOffset + ')');
}
},
d3_defaultLocale: {
format: format,
formatPrefix: formatPrefix
},
d3_defaultFormatSpecifier: '.01f',
d3_defaultDelimiter: 'to'
}
Example #18
Source File: log.js From cs-wiki with GNU General Public License v3.0 | 4 votes |
export function loggish(transform) {
const scale = transform(transformLog, transformExp);
const domain = scale.domain;
let base = 10;
let logs;
let pows;
function rescale() {
logs = logp(base), pows = powp(base);
if (domain()[0] < 0) {
logs = reflect(logs), pows = reflect(pows);
transform(transformLogn, transformExpn);
} else {
transform(transformLog, transformExp);
}
return scale;
}
scale.base = function(_) {
return arguments.length ? (base = +_, rescale()) : base;
};
scale.domain = function(_) {
return arguments.length ? (domain(_), rescale()) : domain();
};
scale.ticks = count => {
const d = domain();
let u = d[0];
let v = d[d.length - 1];
const r = v < u;
if (r) ([u, v] = [v, u]);
let i = logs(u);
let j = logs(v);
let k;
let t;
const n = count == null ? 10 : +count;
let z = [];
if (!(base % 1) && j - i < n) {
i = Math.floor(i), j = Math.ceil(j);
if (u > 0) for (; i <= j; ++i) {
for (k = 1; k < base; ++k) {
t = i < 0 ? k / pows(-i) : k * pows(i);
if (t < u) continue;
if (t > v) break;
z.push(t);
}
} else for (; i <= j; ++i) {
for (k = base - 1; k >= 1; --k) {
t = i > 0 ? k / pows(-i) : k * pows(i);
if (t < u) continue;
if (t > v) break;
z.push(t);
}
}
if (z.length * 2 < n) z = ticks(u, v, n);
} else {
z = ticks(i, j, Math.min(j - i, n)).map(pows);
}
return r ? z.reverse() : z;
};
scale.tickFormat = (count, specifier) => {
if (count == null) count = 10;
if (specifier == null) specifier = base === 10 ? "s" : ",";
if (typeof specifier !== "function") {
if (!(base % 1) && (specifier = formatSpecifier(specifier)).precision == null) specifier.trim = true;
specifier = format(specifier);
}
if (count === Infinity) return specifier;
const k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?
return d => {
let i = d / pows(Math.round(logs(d)));
if (i * base < base - 0.5) i *= base;
return i <= k ? specifier(d) : "";
};
};
scale.nice = () => {
return domain(nice(domain(), {
floor: x => pows(Math.floor(logs(x))),
ceil: x => pows(Math.ceil(logs(x)))
}));
};
return scale;
}
Example #19
Source File: SamplePlot.js From likelihood with MIT License | 4 votes |
SampleChart = props => {
const vizRef = useRef(null);
// Stuff
const margin = { top: 60, right: 20, bottom: 30, left: 50 };
const durationTime = 200;
const w = props.width - margin.left - margin.right;
const h = props.width * aspect - margin.top - margin.bottom;
const sample = props.sample;
const sigma = Math.sqrt(props.sigma2)
const sigmaTheta = Math.sqrt(props.sigma2Theta)
// x.values
const x_start = props.muTheta - 10 * sigmaTheta;
const x_end = props.muTheta + 10 * sigmaTheta;
const x_start2 = props.mu - 3 * sigma;
const x_end2 = props.mu + 3 * sigma;
const x = range( props.mu - 3 * sigma,
props.mu + 3 * sigma, Math.abs(x_start2 - x_end2) / 50);
x.push(x_end)
x.unshift(x_start)
// Data sets
const data1 = genData(props.mu, sigma, x);
// Axes min and max
const x_max = props.muTheta + sigmaTheta * 5;
const x_min = props.muTheta - sigmaTheta * 5;
//const y_max = max(data1.y);
const y_max = 0.04;
// Create scales
const yScale = scaleLinear()
.domain([0, y_max])
.range([h, 0]);
const xScale = scaleLinear()
.domain([x_min, x_max])
.range([0, w]);
// Scales and Axis
const xAxis = axisBottom(xScale);
const yAxis = axisLeft(yScale);
// Update
useEffect(() => {
createSampleChart(durationTime);
}, [props.mu, props.sigma2, props.highlight, props.sample, w]);
// Tooltip
const Tooltip = ({ d, i }) => {
const x = xScale(d);
const L = normal.pdf(d, props.mu, sigma);
const y = yScale(L);
const path = topTooltipPath(150, 50, 10, 10);
const width = 150;
const eqLogLik = katex.renderToString(`\\ell_{${i + 1}} = `, {
displayMode: false,
throwOnError: false
});
return (
<g>
<path
d={path}
className="polygonTip1"
transform={`translate(${x + margin.left}, ${y + margin.top })`}
/>
<foreignObject
x={x - width / 2 + margin.left}
y={y }
width={width}
height={50}
>
<div className="vizTooltip">
<p>
<span dangerouslySetInnerHTML={{ __html: eqLogLik }} />
log({format(".2n")(L)})
</p>
</div>
</foreignObject>
</g>
);
};
const createSampleChart = () => {
const node = vizRef.current;
// Line function
const linex = line()
.x(d => xScale(d[0]))
.y(d => yScale(d[1]));
select(node)
.selectAll("g.viz")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// x Axis
select(node)
.selectAll("g.xAxis")
.data([0])
.enter()
.append("g")
.attr("class", "xAxis");
select(node)
.select("g.xAxis")
.attr(
"transform",
"translate(" + margin.left + "," + (h + margin.top) + ")"
)
.call(xAxis);
// y Axis
select(node)
.selectAll("g.yAxis")
.data([0])
.enter()
.append("g")
.attr("class", "yAxis");
select(node)
.select("g.yAxis")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(yAxis);
const gViz = select(node)
.selectAll("g.viz")
.data([0])
.enter()
.append("g")
.attr("class", "viz")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// x label
gViz
.selectAll(".x-label")
.data([0])
.enter()
.append("text")
.style("text-anchor", "middle")
.attr("class", "x-label");
select(node)
.selectAll(".x-label")
.attr(
"transform",
"translate(" + w / 2 + " ," + (h + margin.bottom) + ")"
)
.text(props.xLabel);
// y label
gViz
.selectAll("#y-label")
.data([0])
.enter()
.append("text")
.style("text-anchor", "middle")
.attr("id", "y-label");
select(node)
.selectAll("#y-label")
.attr("transform", "rotate(-90)")
.attr("text-anchor", "middle")
.attr("x", -(h / 2))
.attr("y", -40)
.text("Density");
// Append dists
// DIST1
gViz
.selectAll("#dist1")
.data([data1.data])
.enter()
.append("svg:path")
.attr("d", linex)
.attr("id", "dist1");
select(node)
.selectAll("#dist1")
.data([data1.data])
.attr("d", linex);
// mu vertical lines
const sampleLines = (mu, id) => {
gViz
.selectAll("#" + id)
.data([0])
.enter()
.append("line")
.attr("class", "logLikLines")
.attr("id", id);
select(node)
.selectAll("#" + id)
.data([0])
.attr("x1", xScale(mu))
.attr("x2", xScale(mu))
.attr("y1", yScale(normal.pdf(mu, props.mu, sigma)))
.attr("y2", yScale(0));
};
//muLines(props.mu0, "mu0");
sample.map((x, i) => sampleLines(x, `sample${i}`));
// Points
gViz
.selectAll("circle")
.data(sample)
.enter()
.append("svg:circle")
.attr("cy", d => yScale(normal.pdf(d, props.mu, sigma)))
.attr("cx", d => xScale(d));
select(node)
.selectAll("circle")
.data(sample)
.attr("cy", d => yScale(normal.pdf(d, props.mu, sigma)))
.attr("cx", d => xScale(d))
.attr("class", "sampleCircles")
.on("mouseover", function(d, i) {
props.setHighlight(i);
select(this).attr("r", 10)
})
.on("mouseout", function() {
props.setHighlight();
select(this).attr("r", 5)
})
.attr("r", (d, i) => {
const r = props.highlight == i ? 10 : 5;
return r;
});
};
return (
<svg width={props.width} height={props.width * aspect}>
<g ref={vizRef} />
{props.highlight >= 0 && (
<Tooltip d={sample[props.highlight]} i={props.highlight} />
)}
</svg>
);
}
Example #20
Source File: LogLikPlotSigma.js From likelihood with MIT License | 4 votes |
OverlapChart = props => {
const vizRef = useRef(null);
const dispatch = useContext(VizDispatch);
// Stuff
const margin = { top: 0, right: 20, bottom: 40, left: 50 };
const durationTime = 200;
const w = props.width * 0.4 - margin.left - margin.right;
const h = props.width * 0.75 - margin.top - margin.bottom;
const sample = props.sample;
const deriv = props.deriv;
const data1 = props.data;
// Axes min and max
var yMin, yMax, llTheta;
yMax = 1500;
yMin = 1;
llTheta = useMemo(() => logLikSum(sample, props.mu, props.sigma2), [
props.mu,
props.sigma2,
props.sample
]);
const [spring, set] = useSpring(() => ({
xy: [props.mu, props.sigma2],
immediate: false,
config: { duration: 500 }
}));
set({ xy: [props.mu, props.sigma2], immediate: !props.animating });
const bind = useDrag(({ movement: [mx, my], first, memo }) => {
const muStart = first ? props.mu : memo[0];
const sigma2Start = first ? props.sigma2 : memo[1];
const mu = xScale.invert(xScale(muStart) + mx);
const sigma2 = yScale.invert(yScale(sigma2Start) + my);
dispatch({
name: "contourDrag",
value: { mu: props.mu, sigma2: sigma2 }
});
return [muStart, sigma2Start];
});
const xMin = -100;
const xMax = -20;
const hessian = -10 / (2 * props.sigma2 * props.sigma2);
//const y_max = 0.05;
// Create scales
const yScale = scaleLinear()
.domain([yMin, yMax])
.range([h, 0]);
const xScale = scaleLinear()
.domain([xMin, xMax])
.range([0, w]);
// Scales and Axis
const xAxis = axisBottom(xScale).ticks(3);
const yAxis = axisLeft(yScale);
// Line function
const linex = line()
.x(d => xScale(d[1]))
.y(d => yScale(d[0]));
// Update
useEffect(() => {
createChart(durationTime);
}, [props.mu, props.sigma2, w, props.sample]);
const gradientNext = gradientStep(props);
const gradientNextLL = logLikSum(
sample,
props.mu,
gradientNext.points.sigma2
);
// Tooltip
const Tooltip = ({ theta, thetaLab, ll, deriv }) => {
const x = 0;
const y = 0;
const width = 40;
const path = topTooltipPath(width, 100, 10, 10);
const thetaSymb = thetaLab == "mu" ? "mu" : "sigma^2";
const eqLogLik = katex.renderToString(
`\\frac{\\partial}{\\partial \\${thetaSymb}}\\ell = `,
{
displayMode: false,
throwOnError: false
}
);
return (
<g>
<path
d={path}
className="polygonTip"
transform={`translate(${x + margin.left + 5}, ${y +
margin.top}) rotate(90)`}
/>
<foreignObject
x={x + margin.right / 2 + margin.left}
y={y - margin.bottom + 15}
width={100}
height={50}
>
<div className="vizTooltip">
<p>
<span dangerouslySetInnerHTML={{ __html: eqLogLik }} />
{format(".2f")(deriv)}
</p>
</div>
</foreignObject>
</g>
);
};
const createChart = () => {
const node = vizRef.current;
select(node)
.selectAll("g.viz")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// x Axis
select(node)
.selectAll("g.xAxis")
.data([0])
.enter()
.append("g")
.attr("class", "xAxis");
select(node)
.select("g.xAxis")
.attr(
"transform",
"translate(" + margin.left + "," + (h + margin.top) + ")"
)
.call(xAxis);
// y Axis
select(node)
.selectAll("g.yAxis")
.data([0])
.enter()
.append("g")
.attr("class", "yAxis");
select(node)
.select("g.yAxis")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(yAxis);
const gViz = select(node)
.selectAll("g.viz")
.data([0])
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// x label
gViz
.selectAll(".x-label")
.data([0])
.enter()
.append("text")
.style("text-anchor", "middle")
.attr("class", "x-label MuiTypography-body2");
select(node)
.selectAll(".x-label")
.attr(
"transform",
"translate(" + w / 2 + " ," + (h + margin.bottom - 5) + ")"
)
.text(`ℓ(μ = ${format(".2f")(props.mu)}, σ²)`);
// y label
gViz
.selectAll(".y-label")
.data([0])
.enter()
.append("text")
.style("text-anchor", "middle")
.attr("class", "y-label MuiTypography-body2");
select(node)
.selectAll(".y-label")
.attr("transform", "rotate(-90)")
.attr("text-anchor", "middle")
.attr("x", -(h / 2))
.attr("y", -40)
.text("σ²");
};
const delta = yMax - yMin;
return (
<svg width={props.width} height={h + margin.bottom}>
<g ref={vizRef}>
<g className="viz">
<g clipPath="url(#clipQuadApprox)">
<AnimatedPath
data={data1.data}
x={100}
sigma2={props.sigma2}
xScale={xScale}
yScale={yScale}
linex={linex}
mu={props.mu}
sample={sample}
animating={props.animating}
/>
{props.algo == "newtonRaphson" && (
<NewtonParabola
mu={props.mu}
sigma2={props.sigma2}
yMin={yMin}
yMax={yMax}
xMin={xMin}
xScale={xScale}
yScale={yScale}
linex={linex}
llTheta={llTheta}
deriv={deriv}
hessian={hessian}
count={props.count}
/>
)}
{props.algo == "gradientAscent" && (
<>
<circle
cy={yScale(gradientNext.points.sigma2)}
cx={xScale(gradientNextLL)}
r="5"
className="logLikNewtonX--approx"
/>
<line
className="LogLikNewton--maxima"
x1={xScale(xMin)}
x2={xScale(gradientNextLL)}
y1={yScale(gradientNext.points.sigma2)}
y2={yScale(gradientNext.points.sigma2)}
/>
</>
)}
</g>
</g>
<g clipPath="url(#clipSigma2)">
<animated.g
{...bind()}
transform={spring.xy.interpolate(
(x, y) =>
`translate(${xScale(logLikSum(sample, x, y))}, ${yScale(y)})`
)}
className="draggable"
>
<circle cx={margin.left} cy={0} r="5" className="logLikX" />
<animated.line
className="deriv"
x1={spring.xy.interpolate(
(x, y) =>
margin.left + xScale(xMin - delta * dSigma2(sample, x, y))
)}
x2={spring.xy.interpolate(
(x, y) =>
margin.left + xScale(xMin + delta * dSigma2(sample, x, y))
)}
y1={yScale(yMax - delta)}
y2={yScale(yMax + delta)}
/>
<Tooltip
theta={props.theta}
thetaLab={props.thetaLab}
ll={llTheta}
deriv={deriv}
/>
</animated.g>
</g>
</g>
<defs>
<clipPath id="clipSigma">
<rect id="clip-rect2" x="0" y="-10" width={w} height={h + 10} />
</clipPath>
<clipPath id="clipSigma2">
<rect
id="clip-rect2"
x={margin.left}
y={-10}
width={w + 100}
height={h + 10}
/>
</clipPath>
<clipPath id="clipQuadApprox">
<rect id="clip-rect2" x="0" y="-10" width={h + 100} height={h + 10} />
</clipPath>
</defs>
</svg>
);
}
Example #21
Source File: LogLikPlot.js From likelihood with MIT License | 4 votes |
logLikCart = props => {
const vizRef = useRef(null);
const dispatch = useContext(VizDispatch);
// Stuff
const margin = { top: 60, right: 20, bottom: 40, left: 50 };
const durationTime = 200;
const w = props.width - margin.left - margin.right;
const h = props.width * 0.4 - margin.top - margin.bottom;
const sample = props.sample;
const sigmaTheta = Math.sqrt(props.sigma2Theta);
const deriv = props.deriv;
const data1 = props.data;
// Axes min and max
var xMax, xMin, llTheta;
if (props.thetaLab == "mu") {
xMax = props.muTheta + sigmaTheta * 5;
xMin = props.muTheta - sigmaTheta * 5;
llTheta = useMemo(() => logLikSum(sample, props.mu, props.sigma2), [
props.mu,
props.sigma2,
props.sample
]);
} else if (props.thetaLab == "sigma") {
const sigma2MLE = props.sigma2Theta;
xMax = sigma2MLE + sigma2MLE * 2;
xMin = sigma2MLE - sigma2MLE * 5;
xMin = xMin < 0 ? 0.1 : xMin;
llTheta = useMemo(() =>
logLikSum(sample, props.mu, props.sigma2, [
props.mu,
props.sigma2,
props.sample
])
);
}
const x_range = range(xMin, xMax, Math.abs(xMax - xMin) / 50);
const newtonParabola = x_range.map(x1 => {
return [
x1,
quadraticApprox(x1 - props.mu, 1, llTheta, deriv, -10 / props.sigma2)
];
});
const yMin = -100;
const yMax = -20;
const [spring, set] = useSpring(() => ({
xy: [props.mu, props.sigma2],
immediate: false,
config: { duration: 500 }
}));
set({ xy: [props.mu, props.sigma2], immediate: !props.animating });
const bind = useDrag(({ movement: [mx, my], first, memo }) => {
const muStart = first ? props.mu : memo[0];
const sigma2Start = first ? props.sigma2 : memo[1];
const mu = xScale.invert(xScale(muStart) + mx);
const sigma2 = yScale.invert(yScale(sigma2Start) + my);
dispatch({
name: "contourDrag",
value: { mu: mu, sigma2: props.sigma2 }
});
return [muStart, sigma2Start];
});
//const yMax = 0.05;
// Create scales
const yScale = scaleLinear()
.domain([yMin, yMax])
.range([h, 0]);
const xScale = scaleLinear()
.domain([xMin, xMax])
.range([0, w]);
// Scales and Axis
const xAxis = axisBottom(xScale);
const yAxis = axisLeft(yScale).ticks(4);
// Line function
const linex = line()
.x(d => xScale(d[0]))
.y(d => yScale(d[1]));
// Update
useEffect(() => {
createChart(durationTime);
}, [props.mu, props.sigma2, w, props.sample]);
const gradientNext = gradientStep(props);
const gradientNextLL = logLikSum(
sample,
gradientNext.points.mu,
props.sigma2
);
// Tooltip
const Tooltip = ({ theta, thetaLab, ll, deriv }) => {
const x = 0;
const y = 0;
const width = 100;
const path = topTooltipPath(width, 40, 10, 10);
const thetaSymb = thetaLab == "mu" ? "mu" : "sigma^2";
const eqLogLik = katex.renderToString(
`\\frac{\\partial}{\\partial \\${thetaSymb}}\\ell = `,
{
displayMode: false,
throwOnError: false
}
);
return (
<g>
<path
d={path}
className="polygonTip"
transform={`translate(${x + margin.left}, ${y + margin.top - 5})`}
/>
<foreignObject
x={x - width / 2 + margin.left}
y={y}
width={width}
height={50}
>
<div className="vizTooltip">
<p>
<span dangerouslySetInnerHTML={{ __html: eqLogLik }} />
{format(".2f")(deriv)}
</p>
</div>
</foreignObject>
</g>
);
};
const createChart = () => {
const node = vizRef.current;
select(node)
.selectAll("g.viz")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// x Axis
select(node)
.selectAll("g.xAxis")
.data([0])
.enter()
.append("g")
.attr("class", "xAxis");
select(node)
.select("g.xAxis")
.attr(
"transform",
"translate(" + margin.left + "," + (h + margin.top) + ")"
)
.call(xAxis);
// y Axis
select(node)
.selectAll("g.yAxis")
.data([0])
.enter()
.append("g")
.attr("class", "yAxis");
select(node)
.select("g.yAxis")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(yAxis);
const gViz = select(node)
.selectAll("g.viz")
.data([0])
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// x label
gViz
.selectAll(".x-label")
.data([0])
.enter()
.append("text")
.style("text-anchor", "middle")
.attr("class", "x-label MuiTypography-body1");
select(node)
.selectAll(".x-label")
.attr(
"transform",
"translate(" + w / 2 + " ," + (h + margin.bottom - 5) + ")"
)
.text(props.thetaLab == "mu" ? "μ" : "σ²");
// y label
gViz
.selectAll(".y-label")
.data([0])
.enter()
.append("text")
.style("text-anchor", "middle")
.attr("class", "y-label MuiTypography-body2");
select(node)
.selectAll(".y-label")
.attr("transform", "rotate(-90)")
.attr("text-anchor", "middle")
.attr("x", -(h / 2))
.attr("y", -40)
.text(`ℓ(μ, σ² = ${format(".2f")(props.sigma2)})`);
};
const delta = xMax - xMin;
return (
<svg width={props.width} height={props.width * 0.4}>
<g ref={vizRef}>
<g className="viz">
<g clipPath="url(#clipMu)">
<AnimatedPath
data={data1.data}
x={100}
sigma2={props.sigma2}
xScale={xScale}
yScale={yScale}
linex={linex}
mu={props.mu}
sample={sample}
animating={props.animating}
className="LogLikMu"
/>
{props.algo == "newtonRaphson" && (
<AnimatedPath
data={newtonParabola}
x={100}
sigma2={props.sigma2}
xScale={xScale}
yScale={yScale}
linex={linex}
mu={props.mu}
sample={sample}
animating={props.animating}
className="LogLikNewton"
/>
)}
{props.algo == "gradientAscent" && (
<>
<circle
cx={xScale(gradientNext.points.mu)}
cy={yScale(gradientNextLL)}
r="5"
className="logLikNewtonX--approx"
/>
<line
className="LogLikNewton--maxima"
y1={yScale(yMin)}
y2={yScale(gradientNextLL)}
x1={xScale(gradientNext.points.mu)}
x2={xScale(gradientNext.points.mu)}
/>
</>
)}
</g>
</g>
</g>
<g clipPath="url(#clipMu2)">
<animated.g
{...bind()}
transform={spring.xy.interpolate(
(x, y) =>
`translate(${xScale(x)}, ${yScale(logLikSum(sample, x, y))})`
)}
className="draggable"
>
<circle
cx={margin.left}
cy={margin.top}
r="5"
className="logLikX"
/>
<animated.line
className="deriv"
y1={spring.xy.interpolate(
(x, y) =>
margin.top + yScale(yMax - delta * dMu(10, x, props.muHat, y))
)}
y2={spring.xy.interpolate(
(x, y) =>
margin.top + yScale(yMax + delta * dMu(10, x, props.muHat, y))
)}
x1={margin.left + xScale(xMin - delta)}
x2={margin.left + xScale(xMin + delta)}
/>
<Tooltip
theta={props.theta}
thetaLab={props.thetaLab}
ll={llTheta}
deriv={deriv}
/>
</animated.g>
</g>
<defs>
<clipPath id="clipMu">
<rect id="clip-rectMu" x="0" y="-10" width={w} height={h + 10} />
</clipPath>
<clipPath id="clipMu2">
<rect
id="clip-rectMu"
x={margin.left}
y={-margin.bottom}
width={w}
height={h + 100}
/>
</clipPath>
</defs>
</svg>
);
}
Example #22
Source File: ContourLogLik.js From likelihood with MIT License | 4 votes |
ContourChart = props => {
const vizRef = useRef(null);
const dispatch = useContext(VizDispatch);
// Stuff
const margin = { top: 0, right: 20, bottom: 40, left: 50 };
const w = props.width - margin.left - margin.right;
const h = props.width * 0.75 - margin.top - margin.bottom;
const sample = props.sample;
const sigmaTheta = Math.sqrt(props.sigma2Theta);
const muMax = props.muTheta + sigmaTheta * 5;
const muMin = props.muTheta - sigmaTheta * 5;
const sigma2MLE = props.sigma2Theta;
const sigma2Max = 1500;
const sigma2Min = 1;
// For gradient ascent illustration
const [spring, set] = useSpring(() => ({
xy: [props.mu, props.sigma2],
immediate: false,
config: { duration: 500 }
}));
const bind = useDrag(({ movement: [mx, my], first, memo }) => {
const muStart = first ? props.mu : memo[0];
const sigma2Start = first ? props.sigma2 : memo[1];
const mu = xScale.invert(xScale(muStart) + mx);
const sigma2 = yScale.invert(yScale(sigma2Start) + my);
dispatch({
name: "contourDrag",
value: { mu: mu, sigma2: sigma2 }
});
return [muStart, sigma2Start];
});
const iterate = () => {
dispatch({
name: "algoIterate",
value: {
increment: 1,
}
});
};
useInterval(() => {
iterate();
}, props.algoDelay);
set({ xy: [props.mu, props.sigma2], immediate: !props.animating });
const llMin = -300;
const llMax = -20;
const thresholds = useMemo(
() => range(llMin, llMax, (llMax - llMin) / 100),
[]
);
const yScale = scaleLinear([sigma2Min, sigma2Max], [h, 0]);
const xScale = scaleLinear([muMin, muMax], [0, w]);
const linex = useMemo(
() =>
line()
.x(d => xScale(d.mu))
.y(d => yScale(d.sigma2)),
[w]
);
const grid = useMemo(
() => createGrid(muMin, muMax, sigma2Min, sigma2Max, sample),
[props.sample]
);
const color = useMemo(
() =>
scaleLinear()
.domain([-100, max(grid)])
.range(["#82b3aa", "#fff"])
.interpolate(interpolateRgb.gamma(0.6)),
[props.sample]
);
const contour = useMemo(
() =>
contours()
.size([grid.n, grid.m])
.thresholds(thresholds)(grid)
.map(({ type, value, coordinates }) => {
return {
type,
value,
coordinates: coordinates.map(rings => {
return rings.map(points => {
return points.map(([mu, sigma2]) => [
xScale(muMin + mu * grid.muStep),
yScale(sigma2Min + sigma2 * grid.sigmaStep)
]);
});
})
};
}),
[props.sample, w]
);
const contourPaths = useMemo(
() =>
contour.map((d, i) => {
return (
<path
d={geoPath()(d)}
className="contour"
fill={color(d.value)}
fillOpacity={1}
stroke="#485460"
strokeWidth={i % 5 ? 0.5 : 1.5}
strokeOpacity={0.75}
strokeLinejoin="round"
key={i}
/>
);
}),
[props.sample, w]
);
const ll = useMemo(
() => format(".2f")(logLikSum(sample, props.mu, props.sigma2)),
[sample, props.mu, props.sigma2]
);
return (
<svg width={props.width} height={h + margin.bottom}>
<g ref={vizRef}>
<g
className="viz"
transform={"translate(" + margin.left + "," + 0 + ")"}
>
{contourPaths}
<animated.line
x1={xScale(muMin)}
x2={xScale(muMax)}
y1={0}
y2={0}
className="LogLikMu"
transform={spring.xy.interpolate(
(x, y) => `translate(0, ${yScale(y)})`
)}
/>
<animated.line
y1={yScale(sigma2Min)}
y2={yScale(sigma2Max)}
x1={0}
x2={0}
transform={spring.xy.interpolate(
(x, y) => `translate(${xScale(x)}, 0)`
)}
className="LogLikSigma"
/>
<animated.g
{...bind()}
transform={spring.xy.interpolate(
(x, y) => `translate(${xScale(x)}, ${yScale(y)})`
)}
className="draggable"
>
<circle cx={0} cy={0} r="5" className="logLikX" />
<Tooltip x={0} y={0} equation={eqLogLik(ll)} margin={margin} />
</animated.g>
<path d={linex(props.drawGradientPath)} className="gradientDescent" />
<rect
id="clip-rect"
x="0"
y="0"
width={w}
height={h}
fill="none"
stroke="#fff"
strokeWidth="3px"
/>
</g>
</g>
</svg>
);
}
Example #23
Source File: log.js From cs-wiki with GNU General Public License v3.0 | 4 votes |
export function loggish(transform) {
var scale = transform(transformLog, transformExp),
domain = scale.domain,
base = 10,
logs,
pows;
function rescale() {
logs = logp(base), pows = powp(base);
if (domain()[0] < 0) {
logs = reflect(logs), pows = reflect(pows);
transform(transformLogn, transformExpn);
} else {
transform(transformLog, transformExp);
}
return scale;
}
scale.base = function(_) {
return arguments.length ? (base = +_, rescale()) : base;
};
scale.domain = function(_) {
return arguments.length ? (domain(_), rescale()) : domain();
};
scale.ticks = function(count) {
var d = domain(),
u = d[0],
v = d[d.length - 1],
r;
if (r = v < u) i = u, u = v, v = i;
var i = logs(u),
j = logs(v),
p,
k,
t,
n = count == null ? 10 : +count,
z = [];
if (!(base % 1) && j - i < n) {
i = Math.round(i) - 1, j = Math.round(j) + 1;
if (u > 0) for (; i < j; ++i) {
for (k = 1, p = pows(i); k < base; ++k) {
t = p * k;
if (t < u) continue;
if (t > v) break;
z.push(t);
}
} else for (; i < j; ++i) {
for (k = base - 1, p = pows(i); k >= 1; --k) {
t = p * k;
if (t < u) continue;
if (t > v) break;
z.push(t);
}
}
} else {
z = ticks(i, j, Math.min(j - i, n)).map(pows);
}
return r ? z.reverse() : z;
};
scale.tickFormat = function(count, specifier) {
if (specifier == null) specifier = base === 10 ? ".0e" : ",";
if (typeof specifier !== "function") specifier = format(specifier);
if (count === Infinity) return specifier;
if (count == null) count = 10;
var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?
return function(d) {
var i = d / pows(Math.round(logs(d)));
if (i * base < base - 0.5) i *= base;
return i <= k ? specifier(d) : "";
};
};
scale.nice = function() {
return domain(nice(domain(), {
floor: function(x) { return pows(Math.floor(logs(x))); },
ceil: function(x) { return pows(Math.ceil(logs(x))); }
}));
};
return scale;
}
Example #24
Source File: indexRollupNext.js From t-viSNE with MIT License | 4 votes |
function color() {
var scale = scaleLinear(),
shape = "rect",
shapeWidth = 15,
shapeHeight = 15,
shapeRadius = 10,
shapePadding = 2,
cells = [5],
cellFilter = void 0,
labels = [],
classPrefix = "",
useClass = false,
title = "",
locale = helper.d3_defaultLocale,
specifier = helper.d3_defaultFormatSpecifier,
labelOffset = 10,
labelAlign = "middle",
labelDelimiter = helper.d3_defaultDelimiter,
labelWrap = void 0,
orient = "vertical",
ascending = false,
path = void 0,
titleWidth = void 0,
legendDispatcher = dispatch("cellover", "cellout", "cellclick");
function legend(svg) {
var type = helper.d3_calcType(scale, ascending, cells, labels, locale.format(specifier), labelDelimiter),
legendG = svg.selectAll("g").data([scale]);
legendG.enter().append("g").attr("class", classPrefix + "legendCells");
if (cellFilter) {
helper.d3_filterCells(type, cellFilter);
}
var cell = svg.select("." + classPrefix + "legendCells").selectAll("." + classPrefix + "cell").data(type.data);
var cellEnter = cell.enter().append("g").attr("class", classPrefix + "cell");
cellEnter.append(shape).attr("class", classPrefix + "swatch");
var shapes = svg.selectAll("g." + classPrefix + "cell " + shape + "." + classPrefix + "swatch").data(type.data);
//add event handlers
helper.d3_addEvents(cellEnter, legendDispatcher);
cell.exit().transition().style("opacity", 0).remove();
shapes.exit().transition().style("opacity", 0).remove();
shapes = shapes.merge(shapes);
helper.d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, path);
var text = helper.d3_addText(svg, cellEnter, type.labels, classPrefix, labelWrap);
// we need to merge the selection, otherwise changes in the legend (e.g. change of orientation) are applied only to the new cells and not the existing ones.
cell = cellEnter.merge(cell);
// sets placement
var textSize = text.nodes().map(function (d) {
return d.getBBox();
}),
shapeSize = shapes.nodes().map(function (d) {
return d.getBBox();
});
//sets scale
//everything is fill except for line which is stroke,
if (!useClass) {
if (shape == "line") {
shapes.style("stroke", type.feature);
} else {
shapes.style("fill", type.feature);
}
} else {
shapes.attr("class", function (d) {
return classPrefix + "swatch " + type.feature(d);
});
}
var cellTrans = void 0,
textTrans = void 0,
textAlign = labelAlign == "start" ? 0 : labelAlign == "middle" ? 0.5 : 1;
//positions cells and text
if (orient === "vertical") {
(function () {
var cellSize = textSize.map(function (d, i) {
return Math.max(d.height, shapeSize[i].height);
});
cellTrans = function cellTrans(d, i) {
var height = sum(cellSize.slice(0, i));
return "translate(0, " + (height + i * shapePadding) + ")";
};
textTrans = function textTrans(d, i) {
return "translate( " + (shapeSize[i].width + shapeSize[i].x + labelOffset) + ", " + (shapeSize[i].y + shapeSize[i].height / 2 + 5) + ")";
};
})();
} else if (orient === "horizontal") {
cellTrans = function cellTrans(d, i) {
return "translate(" + i * (shapeSize[i].width + shapePadding) + ",0)";
};
textTrans = function textTrans(d, i) {
return "translate(" + (shapeSize[i].width * textAlign + shapeSize[i].x) + ",\n " + (shapeSize[i].height + shapeSize[i].y + labelOffset + 8) + ")";
};
}
helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);
helper.d3_title(svg, title, classPrefix, titleWidth);
cell.transition().style("opacity", 1);
}
legend.scale = function (_) {
if (!arguments.length) return scale;
scale = _;
return legend;
};
legend.cells = function (_) {
if (!arguments.length) return cells;
if (_.length > 1 || _ >= 2) {
cells = _;
}
return legend;
};
legend.cellFilter = function (_) {
if (!arguments.length) return cellFilter;
cellFilter = _;
return legend;
};
legend.shape = function (_, d) {
if (!arguments.length) return shape;
if (_ == "rect" || _ == "circle" || _ == "line" || _ == "path" && typeof d === "string") {
shape = _;
path = d;
}
return legend;
};
legend.shapeWidth = function (_) {
if (!arguments.length) return shapeWidth;
shapeWidth = +_;
return legend;
};
legend.shapeHeight = function (_) {
if (!arguments.length) return shapeHeight;
shapeHeight = +_;
return legend;
};
legend.shapeRadius = function (_) {
if (!arguments.length) return shapeRadius;
shapeRadius = +_;
return legend;
};
legend.shapePadding = function (_) {
if (!arguments.length) return shapePadding;
shapePadding = +_;
return legend;
};
legend.labels = function (_) {
if (!arguments.length) return labels;
labels = _;
return legend;
};
legend.labelAlign = function (_) {
if (!arguments.length) return labelAlign;
if (_ == "start" || _ == "end" || _ == "middle") {
labelAlign = _;
}
return legend;
};
legend.locale = function (_) {
if (!arguments.length) return locale;
locale = formatLocale(_);
return legend;
};
legend.labelFormat = function (_) {
if (!arguments.length) return legend.locale().format(specifier);
specifier = formatSpecifier(_);
return legend;
};
legend.labelOffset = function (_) {
if (!arguments.length) return labelOffset;
labelOffset = +_;
return legend;
};
legend.labelDelimiter = function (_) {
if (!arguments.length) return labelDelimiter;
labelDelimiter = _;
return legend;
};
legend.labelWrap = function (_) {
if (!arguments.length) return labelWrap;
labelWrap = _;
return legend;
};
legend.useClass = function (_) {
if (!arguments.length) return useClass;
if (_ === true || _ === false) {
useClass = _;
}
return legend;
};
legend.orient = function (_) {
if (!arguments.length) return orient;
_ = _.toLowerCase();
if (_ == "horizontal" || _ == "vertical") {
orient = _;
}
return legend;
};
legend.ascending = function (_) {
if (!arguments.length) return ascending;
ascending = !!_;
return legend;
};
legend.classPrefix = function (_) {
if (!arguments.length) return classPrefix;
classPrefix = _;
return legend;
};
legend.title = function (_) {
if (!arguments.length) return title;
title = _;
return legend;
};
legend.titleWidth = function (_) {
if (!arguments.length) return titleWidth;
titleWidth = _;
return legend;
};
legend.textWrap = function (_) {
if (!arguments.length) return textWrap;
textWrap = _;
return legend;
};
legend.on = function () {
var value = legendDispatcher.on.apply(legendDispatcher, arguments);
return value === legendDispatcher ? legend : value;
};
return legend;
}
Example #25
Source File: indexRollupNext.js From t-viSNE with MIT License | 4 votes |
function size() {
var scale = scaleLinear(),
shape = "rect",
shapeWidth = 15,
shapePadding = 2,
cells = [5],
cellFilter = void 0,
labels = [],
classPrefix = "",
title = "",
locale = helper.d3_defaultLocale,
specifier = helper.d3_defaultFormatSpecifier,
labelOffset = 10,
labelAlign = "middle",
labelDelimiter = helper.d3_defaultDelimiter,
labelWrap = void 0,
orient = "vertical",
ascending = false,
path = void 0,
titleWidth = void 0,
legendDispatcher = dispatch("cellover", "cellout", "cellclick");
function legend(svg) {
var type = helper.d3_calcType(scale, ascending, cells, labels, locale.format(specifier), labelDelimiter),
legendG = svg.selectAll("g").data([scale]);
if (cellFilter) {
helper.d3_filterCells(type, cellFilter);
}
legendG.enter().append("g").attr("class", classPrefix + "legendCells");
var cell = svg.select("." + classPrefix + "legendCells").selectAll("." + classPrefix + "cell").data(type.data);
var cellEnter = cell.enter().append("g").attr("class", classPrefix + "cell");
cellEnter.append(shape).attr("class", classPrefix + "swatch");
var shapes = svg.selectAll("g." + classPrefix + "cell " + shape + "." + classPrefix + "swatch");
//add event handlers
helper.d3_addEvents(cellEnter, legendDispatcher);
cell.exit().transition().style("opacity", 0).remove();
shapes.exit().transition().style("opacity", 0).remove();
shapes = shapes.merge(shapes);
//creates shape
if (shape === "line") {
helper.d3_drawShapes(shape, shapes, 0, shapeWidth);
shapes.attr("stroke-width", type.feature);
} else {
helper.d3_drawShapes(shape, shapes, type.feature, type.feature, type.feature, path);
}
var text = helper.d3_addText(svg, cellEnter, type.labels, classPrefix, labelWrap);
// we need to merge the selection, otherwise changes in the legend (e.g. change of orientation) are applied only to the new cells and not the existing ones.
cell = cellEnter.merge(cell);
//sets placement
var textSize = text.nodes().map(function (d) {
return d.getBBox();
}),
shapeSize = shapes.nodes().map(function (d, i) {
var bbox = d.getBBox();
var stroke = scale(type.data[i]);
if (shape === "line" && orient === "horizontal") {
bbox.height = bbox.height + stroke;
} else if (shape === "line" && orient === "vertical") {
bbox.width = bbox.width;
}
return bbox;
});
var maxH = max(shapeSize, function (d) {
return d.height + d.y;
}),
maxW = max(shapeSize, function (d) {
return d.width + d.x;
});
var cellTrans = void 0,
textTrans = void 0,
textAlign = labelAlign == "start" ? 0 : labelAlign == "middle" ? 0.5 : 1;
//positions cells and text
if (orient === "vertical") {
(function () {
var cellSize = textSize.map(function (d, i) {
return Math.max(d.height, shapeSize[i].height);
});
var y = shape == "circle" || shape == "line" ? shapeSize[0].height / 2 : 0;
cellTrans = function cellTrans(d, i) {
var height = sum(cellSize.slice(0, i));
return "translate(0, " + (y + height + i * shapePadding) + ")";
};
textTrans = function textTrans(d, i) {
return "translate( " + (maxW + labelOffset) + ",\n " + (shapeSize[i].y + shapeSize[i].height / 2 + 5) + ")";
};
})();
} else if (orient === "horizontal") {
(function () {
cellTrans = function cellTrans(d, i) {
var width = sum(shapeSize.slice(0, i), function (d) {
return d.width;
});
var y = shape == "circle" || shape == "line" ? maxH / 2 : 0;
return "translate(" + (width + i * shapePadding) + ", " + y + ")";
};
var offset = shape == "line" ? maxH / 2 : maxH;
textTrans = function textTrans(d, i) {
return "translate( " + (shapeSize[i].width * textAlign + shapeSize[i].x) + ",\n " + (offset + labelOffset) + ")";
};
})();
}
helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);
helper.d3_title(svg, title, classPrefix, titleWidth);
cell.transition().style("opacity", 1);
}
legend.scale = function (_) {
if (!arguments.length) return scale;
scale = _;
return legend;
};
legend.cells = function (_) {
if (!arguments.length) return cells;
if (_.length > 1 || _ >= 2) {
cells = _;
}
return legend;
};
legend.cellFilter = function (_) {
if (!arguments.length) return cellFilter;
cellFilter = _;
return legend;
};
legend.shape = function (_, d) {
if (!arguments.length) return shape;
if (_ == "rect" || _ == "circle" || _ == "line") {
shape = _;
path = d;
}
return legend;
};
legend.shapeWidth = function (_) {
if (!arguments.length) return shapeWidth;
shapeWidth = +_;
return legend;
};
legend.shapePadding = function (_) {
if (!arguments.length) return shapePadding;
shapePadding = +_;
return legend;
};
legend.labels = function (_) {
if (!arguments.length) return labels;
labels = _;
return legend;
};
legend.labelAlign = function (_) {
if (!arguments.length) return labelAlign;
if (_ == "start" || _ == "end" || _ == "middle") {
labelAlign = _;
}
return legend;
};
legend.locale = function (_) {
if (!arguments.length) return locale;
locale = formatLocale(_);
return legend;
};
legend.labelFormat = function (_) {
if (!arguments.length) return legend.locale().format(specifier);
specifier = formatSpecifier(_);
return legend;
};
legend.labelOffset = function (_) {
if (!arguments.length) return labelOffset;
labelOffset = +_;
return legend;
};
legend.labelDelimiter = function (_) {
if (!arguments.length) return labelDelimiter;
labelDelimiter = _;
return legend;
};
legend.labelWrap = function (_) {
if (!arguments.length) return labelWrap;
labelWrap = _;
return legend;
};
legend.orient = function (_) {
if (!arguments.length) return orient;
_ = _.toLowerCase();
if (_ == "horizontal" || _ == "vertical") {
orient = _;
}
return legend;
};
legend.ascending = function (_) {
if (!arguments.length) return ascending;
ascending = !!_;
return legend;
};
legend.classPrefix = function (_) {
if (!arguments.length) return classPrefix;
classPrefix = _;
return legend;
};
legend.title = function (_) {
if (!arguments.length) return title;
title = _;
return legend;
};
legend.titleWidth = function (_) {
if (!arguments.length) return titleWidth;
titleWidth = _;
return legend;
};
legend.on = function () {
var value = legendDispatcher.on.apply(legendDispatcher, arguments);
return value === legendDispatcher ? legend : value;
};
return legend;
}
Example #26
Source File: indexRollupNext.js From t-viSNE with MIT License | 4 votes |
function symbol() {
var scale = scaleLinear(),
shape = "path",
shapeWidth = 15,
shapeHeight = 15,
shapeRadius = 10,
shapePadding = 5,
cells = [5],
cellFilter = void 0,
labels = [],
classPrefix = "",
title = "",
locale = helper.d3_defaultLocale,
specifier = helper.d3_defaultFormatSpecifier,
labelAlign = "middle",
labelOffset = 10,
labelDelimiter = helper.d3_defaultDelimiter,
labelWrap = void 0,
orient = "vertical",
ascending = false,
titleWidth = void 0,
legendDispatcher = dispatch("cellover", "cellout", "cellclick");
function legend(svg) {
var type = helper.d3_calcType(scale, ascending, cells, labels, locale.format(specifier), labelDelimiter),
legendG = svg.selectAll("g").data([scale]);
if (cellFilter) {
helper.d3_filterCells(type, cellFilter);
}
legendG.enter().append("g").attr("class", classPrefix + "legendCells");
var cell = svg.select("." + classPrefix + "legendCells").selectAll("." + classPrefix + "cell").data(type.data);
var cellEnter = cell.enter().append("g").attr("class", classPrefix + "cell");
cellEnter.append(shape).attr("class", classPrefix + "swatch");
var shapes = svg.selectAll("g." + classPrefix + "cell " + shape + "." + classPrefix + "swatch");
//add event handlers
helper.d3_addEvents(cellEnter, legendDispatcher);
//remove old shapes
cell.exit().transition().style("opacity", 0).remove();
shapes.exit().transition().style("opacity", 0).remove();
shapes = shapes.merge(shapes);
helper.d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, type.feature);
var text = helper.d3_addText(svg, cellEnter, type.labels, classPrefix, labelWrap);
// we need to merge the selection, otherwise changes in the legend (e.g. change of orientation) are applied only to the new cells and not the existing ones.
cell = cellEnter.merge(cell);
// sets placement
var textSize = text.nodes().map(function (d) {
return d.getBBox();
}),
shapeSize = shapes.nodes().map(function (d) {
return d.getBBox();
});
var maxH = max(shapeSize, function (d) {
return d.height;
}),
maxW = max(shapeSize, function (d) {
return d.width;
});
var cellTrans = void 0,
textTrans = void 0,
textAlign = labelAlign == "start" ? 0 : labelAlign == "middle" ? 0.5 : 1;
//positions cells and text
if (orient === "vertical") {
(function () {
var cellSize = textSize.map(function (d, i) {
return Math.max(maxH, d.height);
});
cellTrans = function cellTrans(d, i) {
var height = sum(cellSize.slice(0, i));
return "translate(0, " + (height + i * shapePadding) + " )";
};
textTrans = function textTrans(d, i) {
return "translate( " + (maxW + labelOffset) + ",\n " + (shapeSize[i].y + shapeSize[i].height / 2 + 5) + ")";
};
})();
} else if (orient === "horizontal") {
cellTrans = function cellTrans(d, i) {
return "translate( " + i * (maxW + shapePadding) + ",0)";
};
textTrans = function textTrans(d, i) {
return "translate( " + (shapeSize[i].width * textAlign + shapeSize[i].x) + ",\n " + (maxH + labelOffset) + ")";
};
}
helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);
helper.d3_title(svg, title, classPrefix, titleWidth);
cell.transition().style("opacity", 1);
}
legend.scale = function (_) {
if (!arguments.length) return scale;
scale = _;
return legend;
};
legend.cells = function (_) {
if (!arguments.length) return cells;
if (_.length > 1 || _ >= 2) {
cells = _;
}
return legend;
};
legend.cellFilter = function (_) {
if (!arguments.length) return cellFilter;
cellFilter = _;
return legend;
};
legend.shapePadding = function (_) {
if (!arguments.length) return shapePadding;
shapePadding = +_;
return legend;
};
legend.labels = function (_) {
if (!arguments.length) return labels;
labels = _;
return legend;
};
legend.labelAlign = function (_) {
if (!arguments.length) return labelAlign;
if (_ == "start" || _ == "end" || _ == "middle") {
labelAlign = _;
}
return legend;
};
legend.locale = function (_) {
if (!arguments.length) return locale;
locale = formatLocale(_);
return legend;
};
legend.labelFormat = function (_) {
if (!arguments.length) return legend.locale().format(specifier);
specifier = formatSpecifier(_);
return legend;
};
legend.labelOffset = function (_) {
if (!arguments.length) return labelOffset;
labelOffset = +_;
return legend;
};
legend.labelDelimiter = function (_) {
if (!arguments.length) return labelDelimiter;
labelDelimiter = _;
return legend;
};
legend.labelWrap = function (_) {
if (!arguments.length) return labelWrap;
labelWrap = _;
return legend;
};
legend.orient = function (_) {
if (!arguments.length) return orient;
_ = _.toLowerCase();
if (_ == "horizontal" || _ == "vertical") {
orient = _;
}
return legend;
};
legend.ascending = function (_) {
if (!arguments.length) return ascending;
ascending = !!_;
return legend;
};
legend.classPrefix = function (_) {
if (!arguments.length) return classPrefix;
classPrefix = _;
return legend;
};
legend.title = function (_) {
if (!arguments.length) return title;
title = _;
return legend;
};
legend.titleWidth = function (_) {
if (!arguments.length) return titleWidth;
titleWidth = _;
return legend;
};
legend.on = function () {
var value = legendDispatcher.on.apply(legendDispatcher, arguments);
return value === legendDispatcher ? legend : value;
};
return legend;
}
Example #27
Source File: MapLegend.js From covid19india-react with MIT License | 4 votes |
function MapLegend({data, statistic, mapViz, mapScale}) {
const {t} = useTranslation();
const svgLegendRef = useRef(null);
const svgLegendChoroRef = useRef(null);
const [wrapperRef, {width}] = useMeasure();
useEffect(() => {
const t = transition().duration(D3_TRANSITION_DURATION);
if (mapViz !== MAP_VIZS.CHOROPLETH) {
const svg = select(svgLegendChoroRef.current);
svg
.select('.ramp')
.transition(t)
.attr('opacity', 0)
.attr('display', 'none')
.attr('xlink:href', null);
svg
.select('.bars')
.selectAll('rect')
.transition(t)
.attr('opacity', 0)
.remove();
svg.selectAll('.axis > *:not(.axistext)').remove();
svg.select('.axistext').text('');
}
if (mapViz !== MAP_VIZS.BUBBLE) {
const svg = select(svgLegendRef.current);
svg
.select('.circles')
.selectAll('circle')
.transition(t)
.attr('r', 0)
.attr('cy', 0)
.remove();
svg.selectAll('.circle-axis > *').remove();
}
if (mapViz !== MAP_VIZS.SPIKES) {
const svg = select(svgLegendRef.current);
svg
.select('.spikes')
.call((g) =>
g.selectAll('path').transition(t).attr('d', spike(0)).remove()
)
.call((g) => g.selectAll('text').remove())
.transition(t)
.selectAll('g')
.remove();
svg.selectAll('.spike-axis > *').remove();
}
}, [mapViz]);
useEffect(() => {
if (!width) return;
const statisticConfig = STATISTIC_CONFIGS[statistic];
const zoom = width / MAP_DIMENSIONS[0];
if (mapViz === MAP_VIZS.BUBBLE) {
const svg = select(svgLegendRef.current);
const [, domainMax] = mapScale.domain();
const legend = svg
.select('.circles')
.attr('transform', `translate(48,40)`)
.attr('text-anchor', 'middle');
const legendRadius = [0.1, 0.4, 1].map((d) => d * domainMax);
legend
.selectAll('circle')
.data(legendRadius)
.join('circle')
.attr('fill', 'none')
.attr('stroke', statisticConfig.color + '70')
.transition(t)
.attr('cy', (d) => -mapScale(d))
.attr('r', (d) => mapScale(d));
const yScale = mapScale.copy().range([0, -2 * mapScale(domainMax)]);
svg
.select('.circle-axis')
.attr('transform', `translate(48,50)`)
.transition(t)
.call(
axisRight(yScale)
.tickSize(0)
.tickPadding(0)
.tickValues(legendRadius)
.tickFormat((num) =>
formatNumber(
num,
statisticConfig.format === 'long'
? 'short'
: statisticConfig.format
)
)
)
.selectAll('.tick text')
.style('text-anchor', 'middle')
.attr('font-size', 10 / zoom);
svg.select('.circle-axis').call((g) => g.select('.domain').remove());
} else if (mapViz === MAP_VIZS.SPIKE) {
const svg = select(svgLegendRef.current);
const ticks = mapScale.ticks(3).slice(1).reverse();
const gap = 28 / zoom;
svg
.select('.spikes')
.attr('transform', `translate(32,24)`)
.selectAll('g')
.data(ticks)
.join((enter) =>
enter.append('g').call((g) =>
g
.append('path')
.attr('fill-opacity', 0.3)
.attr('d', (d) => spike(0))
)
)
.attr('transform', (d, i) => `translate(${i * gap},0)`)
.call((g) =>
g
.select('path')
.transition(t)
.attr('d', (d) => spike(mapScale(d)))
.attr('fill', statisticConfig.color + '70')
.attr('stroke', statisticConfig.color + '70')
);
const xScale = mapScale.copy().range([gap * ticks.length, 0]);
svg
.select('.spike-axis')
.attr('transform', `translate(32,32)`)
.transition(t)
.call(
axisBottom(xScale)
.tickSize(0)
.tickPadding(0)
.tickValues(ticks)
.tickFormat((num) =>
formatNumber(
num,
statisticConfig.format === 'long'
? 'short'
: statisticConfig.format
)
)
)
.selectAll('.tick text')
.style('text-anchor', 'middle')
.attr('font-size', 10 / zoom);
svg.select('.spike-axis').call((g) => g.select('.domain').remove());
} else {
const svg = select(svgLegendChoroRef.current);
svg.call(() =>
legend({
svg: svg,
color: mapScale,
width: width,
height: MAP_LEGEND_HEIGHT,
ticks: 5,
tickFormat: function (d, i, n) {
if (statisticConfig?.mapConfig?.colorScale) {
return d;
} else if (mapViz === MAP_VIZS.CHOROPLETH && !Number.isInteger(d)) {
return '';
} else if (i === n.length - 1) {
return formatNumber(d, statisticConfig.format) + '+';
} else {
return formatNumber(d, statisticConfig.format);
}
},
marginLeft: 2,
marginRight: 0,
})
);
svg.attr('class', statisticConfig?.mapConfig?.colorScale ? 'zone' : '');
}
}, [t, width, statistic, mapScale, mapViz]);
return (
<div
className="svg-parent maplegend"
ref={wrapperRef}
style={{height: 2 * MAP_LEGEND_HEIGHT}}
>
<svg
id="legend"
preserveAspectRatio="xMinYMid meet"
ref={svgLegendRef}
viewBox={`0 0 ${MAP_DIMENSIONS[0]} ${MAP_LEGEND_HEIGHT}`}
>
<g className="circles"></g>
<g className="spikes"></g>
<g className="circle-axis"></g>
<g className="spike-axis"></g>
<g className="axis">
<text className="axistext" />
</g>
</svg>
<svg
id="legend-choro"
preserveAspectRatio="xMinYMid meet"
ref={svgLegendChoroRef}
>
<image className="ramp" preserveAspectRatio="none" />
<g className="bars"></g>
<g className="axis">
<text className="axistext" />
</g>
</svg>
<canvas
className="color-scale"
style={{position: 'absolute', height: 0}}
/>
</div>
);
}
Example #28
Source File: test.legendcolor.js From t-viSNE with MIT License | 4 votes |
// describe('d3-legend', function () {
// var d3Legend
// beforeEach(function () {
// d3Legend = require('../no-extend')
// })
// it('should export an object', function () {
// expect(d3Legend).to.be.an('object')
// })
// it('should have color, size & symbol functions', function () {
// ['color','size','symbol'].forEach(function (fieldName) {
// expect(d3Legend[fieldName]).to.be.a('function')
// })
// })
// })
describe('d3-legend #legendColor', function() {
it('exports a function', function() {
expect(color).to.be.a('function');
});
it('invoking exported function does not throw an error and returns a legend function', function() {
let result;
expect(color).to.be.a('function');
expect(function() {
result = color();
}).to.not.throw();
expect(result).to.be.a('function');
expect(result.name).to.equal('legend');
});
it('errors when not passed a SVG', function() {
let result;
expect(color).to.be.a('function');
expect(function() {
result = color();
}).to.not.throw();
expect(result).to.be.a('function');
expect(result.name).to.equal('legend');
// TODO add formal error handling and assert on error message
// }).to.throw('need to provide SVG');
expect(function() {
result();
}).to.throw();
});
// TODO renable to create failing assertion to verify shapes.data is rebound
it.skip('properly rebinds the updated range data for the legend shapes', function() {
let result, aLegend;
let mockSvg = {
attr(key, val) {
this._attrs[key] = val;
return this;
},
select() { return this; },
append() { return this; },
enter() { return this; },
data() { return this; },
selectAll() {
return this;
}
};
mockSvg._attrs = {};
this._copied = helper.d3_calcType;
helper.d3_calcType = null;
helper.d3_calcType = function() {
expect(arguments.length).to.equal(6);
return {};
};
expect(color).to.be.a('function');
expect(function() {
result = color();
}).to.not.throw();
expect(result).to.be.a('function');
expect(result.name).to.equal('legend');
// TODO add formal error handling and assert on error message
// }).to.throw('need to provide SVG');
expect(function() {
aLegend = result(mockSvg);
}).to.not.throw();
expect(aLegend).to.be.an('Object');
});
it('should have a locale', function () {
let result = color();
expect(result.locale).to.be.a('function');
});
it('should redefine label\'s format with a string', function () {
let result = color();
let testValue = 1.00;
let initial = result.labelFormat();
result.labelFormat('.2f');
expect(initial(testValue)).to.be.not.equal(result.labelFormat()(testValue));
expect(result.labelFormat()(testValue)).to.be.equal('1.00');
});
it('should redefine label\'s format with a format function', function () {
let result = color();
let testValue = 1.00;
let initial = result.labelFormat();
result.labelFormat(format('.2f'));
expect(initial(testValue)).to.be.not.equal(result.labelFormat()(testValue));
expect(result.labelFormat()(testValue)).to.be.equal('1.00');
});
it('should redefine the locale with a new locale definition', function () {
let result = color();
let testValue = 1.00;
let initial = result.labelFormat();
let frFr = {
decimal: ',',
thousands: '.',
grouping: [3],
currency: ['', '\u00a0€'],
percent: "\u202f%"
};
result.locale(frFr)
expect(initial(testValue)).to.be.not.equal(result.labelFormat()(testValue));
expect(result.labelFormat()(testValue)).to.be.equal('1,0')
})
it('should keep the format specifier after a locale update', function () {
let result = color();
let testValue = 1.00;
let initial = result.labelFormat();
let frFr = {
decimal: ',',
thousands: '.',
grouping: [3],
currency: ['', '\u00a0€'],
percent: "\u202f%"
};
result.labelFormat(format('.2f'));
result.locale(frFr)
expect(initial(testValue)).to.be.not.equal(result.labelFormat()(testValue));
expect(result.labelFormat()(testValue)).to.be.equal('1,00')
})
});
Example #29
Source File: Viz.js From likelihood with MIT License | 4 votes |
Content = ({ openSettings, vizState, toggleDrawer }) => {
const classes = useStyles();
const [highlight, setHighlight] = useState();
const theme = useTheme();
const matchesBreak = useMediaQuery(theme.breakpoints.up("sm"));
const {
mu,
muHat,
muNull,
muTheta,
sigma2Theta,
sigma2,
sigma2Hat,
sigma2MleNull,
sample,
n
} = vizState;
// Data sets
const dataMu = genLogLikCurve(sample, mu, sigma2, "mu", muTheta, sigma2Theta);
const dataSigma = genLogLikCurve(
sample,
mu,
sigma2,
"sigma",
muTheta,
sigma2Theta
);
const derivMu = dMu(10, mu, muHat, sigma2);
const derivMuN = dMu(n, muNull, muHat, sigma2Hat);
const derivMuNull = dMu(n, muNull, muHat, sigma2MleNull);
const deriv2MuNull = d2Mu(n, sigma2MleNull);
const estllThetaMLE = estimatedLogLik(n, mu, mu, sigma2Hat);
const estllThetaNull = estimatedLogLik(n, muNull, muHat, sigma2Hat);
const derivSigma2 = dSigma2(sample, mu, sigma2);
const y = vizState.sample.map(y => format(".1f")(y)).join(", ");
const f2n = format(".2n");
const eqDeriv1 = katex.renderToString(
`U(\\mu_0, \\hat\\sigma_0^2) = \\frac{\\partial}{\\partial \\mu_0}\\ell(\\mu_0, \\hat\\sigma_0^2) = ${f2n(
derivMuNull
)} `,
{
displayMode: true,
throwOnError: false
}
);
const eqDeriv2 = katex.renderToString(
`I(\\mu_0, \\hat\\sigma_0^2) = \\frac{\\partial^2}{\\partial \\mu_0^2}\\ell(\\mu_0, \\hat\\sigma_0^2) = ${-f2n(
deriv2MuNull
)}`,
{
displayMode: true,
throwOnError: false
}
);
const eqModel = katex.renderToString("y \\sim \\mathcal N(\\mu, \\sigma^2)", {
displayMode: false,
throwOnError: false
});
return (
<div>
<Container maxWidth="lg">
<Typography variant="h2" align="center" gutterBottom>
Likelihood Calculation
</Typography>
<Container className={classes.textContent}>
<Typography variant="body1" gutterBottom>
Before we do any calculations, we need some data. So, {"here's"} 10
random observations from a normal distribution with unknown mean (μ)
and variance (σ²).
</Typography>
<Typography
variant="body1"
align="center"
gutterBottom
>{`Y = [${y}]`}</Typography>
<Typography variant="body1" gutterBottom>
We also need to assume a model, we're gonna go with the model
that we know generated this data:{" "}
<span dangerouslySetInnerHTML={{ __html: eqModel }} />. The
challenge now is to find what combination of values for μ and σ²
maximize the likelihood of observing this data (given our
assumed model). Try moving the sliders around to see what happens.
</Typography>
</Container>
<div className={classes.stickySlider}>
<Grid
container
direction="column"
justify="center"
alignItems="center"
className={classes.blur}
>
<Slider
name="mu"
label="Mean (μ)"
thetaHat={vizState.muHat}
value={vizState.mu}
max={vizState.sliderMax}
step={vizState.sliderStep}
openSettings={openSettings}
handleDrawer={toggleDrawer}
/>
<Slider
name="sigma2"
label="Variance (σ²)"
thetaHat={vizState.sigma2Hat}
value={vizState.sigma2}
min={1}
max={vizState.sigma2Max}
step={vizState.sliderStep}
openSettings={openSettings}
handleDrawer={toggleDrawer}
/>
</Grid>
<Grid
container
alignItems="flex-start"
justify="flex-end"
direction="row"
>
<ButtonSample
M={vizState.muTheta}
sigma2={vizState.sigma2Theta}
/>
</Grid>
</div>
<Grid
container
spacing={3}
alignItems="center"
direction="row"
justify="center"
className={classes.gridContainer}
>
<Grid item md={6} xs={12}>
<Paper className={classes.sampleDist}>
<ResponsiveChart
chart={SampleDist}
{...vizState}
highlight={highlight}
setHighlight={setHighlight}
/>
</Paper>
</Grid>
<Grid item md={6} xs={12}>
<Paper className={classes.paper}>
<Grid align="bottom" className={classes.logLikSum}>
<Typography variant="body1" gutterBottom>
We can calculate the joint likelihood by multiplying the
densities for all observations. However, often we calculate
the log-likelihood instead, which is
</Typography>
<CalcLogLik
sample={vizState.sample}
mu={vizState.mu}
sigma={vizState.sigma2}
highlight={highlight}
setHighlight={setHighlight}
/>
<Typography variant="body1" gutterBottom>
The combination of parameter values that give the largest
log-likelihood is the maximum likelihood estimates (MLEs).
</Typography>
</Grid>
</Paper>
</Grid>
</Grid>
<Typography variant="h2" align="center" gutterBottom>
Finding the Maximum Likelihood Estimates
</Typography>
<Container className={classes.textContent}>
<MleFirst />
</Container>
<Grid
container
alignItems="flex-end"
direction="row"
justify="center"
spacing={0}
>
<Grid item xs={12} sm={6}>
<Paper className={classes.paper}>
<Typography
variant="h4"
component="h3"
align="center"
style={{
paddingBottom: "0em",
paddingTop: "0.5em",
paddingLeft: "0em"
}}
>
Mean
</Typography>
<ResponsiveChart
chart={LogLikPlot}
{...vizState}
data={dataMu}
theta={mu}
thetaLab="mu"
deriv={derivMu}
/>
<ResponsiveChart
chart={ContourLogLik}
{...vizState}
data={dataSigma}
theta={sigma2}
thetaLab="sigma"
deriv={derivSigma2}
/>
<Typography align="right" variant="caption" component="p">Tip: You can move the values around by dragging them.</Typography>
</Paper>
</Grid>
<Grid item xs={12} sm={6}>
<Paper className={classes.paper}>
<GradientAscent {...vizState} />
<Typography
variant="h4"
component="h3"
align="left"
style={{
paddingBottom: "0.5em",
paddingTop: "1em",
paddingLeft: "3em"
}}
>
Variance
</Typography>
<ResponsiveChart
chart={LogLikPlotSigma}
{...vizState}
data={dataSigma}
theta={sigma2}
thetaLab="sigma"
deriv={derivSigma2}
/>
</Paper>
</Grid>
</Grid>
<Typography
variant="h2"
align="center"
gutterBottom
style={{ paddingTop: "1em" }}
>
Inference
</Typography>
<Container className={classes.textContent}>
<Typography gutterBottom>
After {"we've"} found the MLEs we usually want to make some
inferences, so {"let's"} focus on three common hypothesis tests. Use
the sliders below to change the null hypothesis and the sample size.
</Typography>
</Container>
</Container>
<Container maxWidth="lg">
<Grid container direction="row" justify="center" spacing={3}>
<Grid item md={6} xs={12}>
<Typography variant="h4" component="h2" align="center" gutterBottom>
Illustration
</Typography>
<Slider
name="n"
label="Sample Size (n)"
value={vizState.n}
max={100}
step={1}
openSettings={openSettings}
handleDrawer={toggleDrawer}
/>
<Slider
name="muNull"
label="Null (μ0)"
value={vizState.muNull}
min={70}
max={160}
step={1}
openSettings={openSettings}
handleDrawer={toggleDrawer}
/>
<div>
<p>The score function evaluated at the null is, </p>
<p dangerouslySetInnerHTML={{ __html: eqDeriv1 }} />
<Typography variant="body1">
The observed <b>Fisher information</b> is the negative of the
second derivative. This is related to the curvature of the
likelihood function -- try increasing the sample size and note
that the peak gets narrower around the MLE and that the{" "}
<em>information</em> increases. The inverse of I is also the
variance of the MLE.
</Typography>
<p dangerouslySetInnerHTML={{ __html: eqDeriv2 }} />
</div>
<Paper className={classes.paper}>
<ResponsiveChart
chart={CurvaturePlot}
{...vizState}
theta={mu}
thetaLab="mu"
llThetaMLE={estllThetaMLE}
llThetaNull={estllThetaNull}
deriv={derivMuN}
/>
</Paper>
</Grid>
<Grid item md={6} xs={12}>
<Typography variant="h4" component="h2" align="center" gutterBottom>
Hypothesis Tests
</Typography>
<TestTabs
muNull={muNull}
muHat={muHat}
sigma2={sigma2Hat}
sigma2Null={sigma2MleNull}
derivMuNull={derivMuNull}
deriv2MuNull={deriv2MuNull}
n={n}
/>
</Grid>
</Grid>
</Container>
</div>
);
}