Skip to content

Instantly share code, notes, and snippets.

@GerHobbelt
Forked from bsr203/index.html
Created September 8, 2012 03:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save GerHobbelt/3671592 to your computer and use it in GitHub Desktop.
Save GerHobbelt/3671592 to your computer and use it in GitHub Desktop.
Help on mapping to Cartesian coordinate (log scale)
# Editor backup files
*.bak
*~
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<link type="text/css" rel="stylesheet" href="style.css"/>
</head>
<body>
<div id="chart"></div>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
//Width and height
var w = 200;
var h = 200;
var padding = 8;
var scale_padding = 20; // space to show axes
var dataset = [
[80, 20, 10, 60] ]; // x, y, w, h
//Create scale functions
var xScale = d3.scale.log()
.domain([10, d3.max(dataset, function (d) {
return (100);
})])
.range([padding + scale_padding, w - padding]);
var yScale = d3.scale.log()
.domain([10, d3.max(dataset, function (d) {
return (100);
})])
.range([h - padding - scale_padding, padding]);
//Define X axis
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
// log axis has very ugly tickFormat by default (IMHO)
.tickFormat(function(d) {
if (d < 30 || d == 50 || d >= 100)
return String(d);
return "";
})
.ticks(5);
//Define Y axis
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
// log axis has very ugly tickFormat by default (IMHO)
.tickFormat(function(d) {
if (d < 30 || d == 50 || d >= 100)
return String(d);
return "";
})
.ticks(5);
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Create circles
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
/*
Your y-axis is -linear and SVG doesn't accept negative widths, not does it accept x2/y2 < x1/y1 if you
would use <rect x1 y1 x2 y2> instead, so coordinate pair flipping is in order...
This is the way to do it, particularly important when your scales are not linear (but, say, logarithmic),
but keep in mind that YOU must still guarantee that those width & hieight values are always positive!
Of course, such work might best be done in the preparation phase rather than right here.
*/
.attr("x", function (d) {
var x = Math.min(xScale(d[0]), xScale(d[0] + d[2]));
return x;
})
.attr("y", function (d) {
var y = Math.min(yScale(d[1]), yScale(d[1] + d[3]));
return y;
})
.attr("width", function (d) {
// return xScale(d[2]); -- only works like that for +linear scale;
var x2 = Math.max(xScale(d[0]), xScale(d[0] + d[2]));
var x1 = Math.min(xScale(d[0]), xScale(d[0] + d[2]));
return x2 - x1;
})
.attr("height", function (d) {
var y2 = Math.max(yScale(d[1]), yScale(d[1] + d[3]));
var y1 = Math.min(yScale(d[1]), yScale(d[1] + d[3]));
return y2 - y1;
});
//Create X axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (h - padding - scale_padding) + ")")
.call(xAxis);
//Create Y axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + (padding + scale_padding) + ",0)")
.call(yAxis);
.axis text, .origintext {
font: 10px sans-serif;
}
.axis path, .axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment