我想在我的密度图中添加带有自定义值的xAxis(参见屏幕截图)。
第一密度“小提琴”代表“0-50”,第二代表“51-100”,第三密度代表“101-150”......第七密度代表“301-350”乘客。它应该类似于以下编辑的屏幕截图中显示的内容。
由于我是d3和javascript的新手,我会很感激详细解答。 我正在使用d3.js(v4)。
这是我目前的代码:
function addViolin(svg, dataOfBin, heightPlot, widthPlot, domain, imposeMax, violinColor){
var data = d3.histogram()
.thresholds(resolution)
(dataOfBin);
var y = d3.scaleLinear()
.range([widthPlot/2, 0])
.domain([0, Math.max(imposeMax, d3.max(data, function(d) { return d.length; }))]);
var x = d3.scaleLinear()
.range([heightPlot, 0])
.domain(domain)
.nice();
var area = d3.area()
.curve(d3.curveCardinal)
.x(function(d) {
if(interpolation=="step-before")
return x(d.x1/2)
return x(d.x);
})
.y0(widthPlot/2)
.y1(function(d) { return y(d.length); });
var line=d3.line()
.curve(d3.curveCardinal)
.x(function(d) {
if(interpolation=="step-before")
return x(d.x1/2)
return x(d.x);
})
.y(function(d) { return y(d.length); });
var gPlus=svg.append("g")
var gMinus=svg.append("g")
gPlus.append("path")
.datum(data)
.attr("class", "area")
.attr("d", area)
.style("fill", violinColor);
gPlus.append("path")
.datum(data)
.attr("class", "violin")
.attr("d", line)
.style("stroke", violinColor);
gMinus.append("path")
.datum(data)
.attr("class", "area")
.attr("d", area)
.style("fill", violinColor);
gMinus.append("path")
.datum(data)
.attr("class", "violin")
.attr("d", line)
.style("stroke", violinColor);
gPlus.attr("transform", "rotate(90,0,0) translate(0,-"+widthPlot+")");//translate(0,-200)");
gMinus.attr("transform", "rotate(90,0,0) scale(1,-1)");
}
function addBoxPlot(svg, dataOfBin, heightPlot, widthPlot, domain, boxPlotWidth, boxColor, boxInsideColor){
}
var marginPlot={top:10, bottom:0, left:30, right:10};
var widthPlot=400;
var heightPlot=220;
var boxWidth=44;
var boxSpacing=10;
var resolution=1000;
var d3ObjId="svgElement1";
var interpolation='step-before';
function showView3(data){
var regionChart = document.getElementById("view3Diagram");
if(regionChart != null){
regionChart.innerHTML = "";
}
var domain=[0, 370];
var y = d3.scaleLinear()
.range([heightPlot-marginPlot.bottom, marginPlot.top])
.domain(domain);
var yAxis = d3.axisLeft()
.scale(y)
.ticks(5)
.tickSize(5,0,5);
var svg = d3.select("div#view3Diagram")
.append("div")
.classed("svg-container2", true)
.append("svg")
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", "0 0 430 430")
.classed("svg-content-responsive", true);
svg.append("line")
.attr("class", "boxplot")
.attr("x1", marginPlot.left)
.attr("x2", widthPlot-marginPlot.right)
.attr("y1", y(0))
.attr("y2", y(0));
for(var i=0; i<data.length; i++){
data[i].Haltezeiten=data[i].Haltezeiten.sort(d3.ascending)
var g=svg.append("g").attr("transform", "translate("+(i*(boxWidth+boxSpacing)+marginPlot.left)+",0)");
addViolin(g, data[i].Haltezeiten, heightPlot, boxWidth, domain, 0.25, "#424242");
addBoxPlot(g, data[i].Haltezeiten, heightPlot, boxWidth, domain, .15, "black", "white");
}
svg.append("g")
.attr('class', 'axis')
.attr("transform", "translate("+marginPlot.left+",0)")
.call(yAxis);
}
答案 0 :(得分:2)
根据您的要求,我会在这个答案中写一个详细的解释(但是,这段代码似乎不是新手的作品......)。
正如我们所看到的,您使用for
循环...
for(var i=0; i<data.length; i++){
...创建<g>
元素,并在其中每个元素中创建小提琴图。
所以,最重要的是data.length
。我们将使用它来设置域或我们的点比例,这将是定制轴的基础&#39;嘀嗒声。跟我来:
如果您将d3.range(data.length)
作为比例范围传递,则您将拥有一组长度相同data.length
的数字。例如,如果data.length
为7,则这是d3.range(data.length)
:
[0, 1, 2, 3, 4, 5, 6]
然后,通过此域,我们可以使用tickFormat
在轴上创建自定义。为此,我将设置一个名为steps
的变量,该变量表示第一个刻度中值之间的差距。在您的示例中:
var steps = 50;
使用域和step
设置,这是tickFormat
中的数学:
.tickFormat(function(d, i) {
return i ? (d * steps) + 1 + " - " + (d * steps + steps)
: (d * steps) + " - " + (d * steps + steps);
});
如果您不知道,这是ternary operator。它基本上是:
condition ? expr1 : expr2
如果condition
为真,则执行expr1
,否则执行expr2
。
确保将相同的范围传递给比例,并相应地对其进行翻译。
以下是正在运行的演示:
var svg = d3.select("svg");
var steps = 50;
var data = ["foo", "foo", "foo", "foo", "foo", "foo", "foo"];
var scale = d3.scalePoint()
.range([20, 470])
.domain(d3.range(data.length));
var axis = d3.axisBottom(scale)
.tickFormat(function(d, i) {
return i ? (d * steps) + 1 + " - " + (d * steps + steps) : (d * steps) + " - " + (d * steps + steps);
});
var gX = svg.append("g")
.attr("transform", "translate(0,50)")
.call(axis)
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="500"></svg>
&#13;