d3.js 可重用图表的 v4 更新元素
d3.js v4 update element of a reusable chart
如本 jsfiddle 所示 https://jsfiddle.net/6o4qu6jh/...
我想使用 input
标签更改此可重复使用图表 (https://bost.ocks.org/mike/chart/) 的轴刻度:
<input type="checkbox" id="linlog">
<label for="linlog"> Lin / Log scale</label>
在此函数中定义的可重用散点图
d3.scatterplot = function(){
[... other initial properties ...]
var xscale = d3.scaleLinear();
var xaxis = d3.axisBottom()
.scale(xscale);
/////////////////////////////
var chart = function(selection){
[... other properties not depending on data ...]
xaxis.scale(xscale)
/////////////////////////////
selection.each(function (data) {
[... other properties depending on data ...]
var svg = d3.select(this).selectAll("svg").data([data]);
var gEnter = svg.enter().append("svg")
.attr("width", 300 )
.attr("height", 100 )
.append("g")
gEnter.append("g")
.attr("transform", "translate(0," + height + ")")
.attr("class", "x axis")
.call(xaxis);
});
return chart;
}
/////////////////////////////
[... other methods ...]
chart.xscale = function(_) {
if (!arguments.length) return xscale;
xscale = _;
if ( _ == "lin" | _ == "linear" )
xscale=d3.scaleLinear()
if ( _ == "log" | _ =="logarithm" | _ =="logarithmic")
xscale=d3.scaleLog()
return chart;
};
return chart;
}
并用这个主要函数初始化:
data=`date,price
Jan 2000,1.46
Feb 2000,16.42
Mar 2000,14.58
Apr 2000,152.43
May 2000,1420.6
Jun 2000,1454.6
Jul 2000,1430.83
Aug 2000,1517.68
Sep 2000,1436.51`
data=d3.csvParse(data)
d3.select("body")
.append("figure")
.datum(data)
.call(scatter
.x("price")
)
它显示了轴,但不幸的是,以下更新代码不起作用:
d3.select("#linlog").on("change", function(){
var l=d3.select(this).property("checked")
var a;
l ? a=scatter.xscale("lin") : a=scatter.xscale("log")
d3.select("figure")
.call(a)
})
有什么问题?
你差不多明白了,主要的问题是在你的 xscale 函数中你没有 return 你的新比例尺。
chart.xscale = function(_) {
//...
return chart; // returning the chart object :(
}
让我们改变一下:
chart.xscale = function(_) {
if (!arguments.length) return xscale;
xscale = _;
if (_ === "lin" | _ === "linear") {
xscale=d3.scaleLinear();
}
if (_ === "log" | _ === "logarithm" | _ === "logarithmic") {
xscale = d3.scaleLog();
}
return xscale;
};
由于我们正在调用一个新的比例,我们需要配置新的范围和域值,让我们添加:
chart.xscale = function(_) {
if (!arguments.length) return xscale;
xscale = _;
if (_ === "lin" | _ === "linear") {
xscale = d3.scaleLinear();
}
if (_ === "log" | _ === "logarithm" | _ === "logarithmic") {
xscale = d3.scaleLog();
}
var width = w - margin.left - margin.right;
var xrange = [0, width];
xscale.range(xrange);
var xdomain = d3.extent(data, function(d) {
return +d[x];
})
xscale.domain(xdomain).nice();
return xscale;
};
终于可以正确调用坐标轴函数了
d3.select("#linlog").on("change", function() {
var l = d3.select(this).property("checked")
var a;
l ? a = scatter.xscale("lin") : a = scatter.xscale("log");
var axis = d3.axisBottom().scale(a);
axis.ticks(5);
d3.selectAll("g .x.axis")
.call(axis)
})
工作 jsfiddle:https://jsfiddle.net/6o4qu6jh/2/
如本 jsfiddle 所示 https://jsfiddle.net/6o4qu6jh/...
我想使用 input
标签更改此可重复使用图表 (https://bost.ocks.org/mike/chart/) 的轴刻度:
<input type="checkbox" id="linlog">
<label for="linlog"> Lin / Log scale</label>
在此函数中定义的可重用散点图
d3.scatterplot = function(){
[... other initial properties ...]
var xscale = d3.scaleLinear();
var xaxis = d3.axisBottom()
.scale(xscale);
/////////////////////////////
var chart = function(selection){
[... other properties not depending on data ...]
xaxis.scale(xscale)
/////////////////////////////
selection.each(function (data) {
[... other properties depending on data ...]
var svg = d3.select(this).selectAll("svg").data([data]);
var gEnter = svg.enter().append("svg")
.attr("width", 300 )
.attr("height", 100 )
.append("g")
gEnter.append("g")
.attr("transform", "translate(0," + height + ")")
.attr("class", "x axis")
.call(xaxis);
});
return chart;
}
/////////////////////////////
[... other methods ...]
chart.xscale = function(_) {
if (!arguments.length) return xscale;
xscale = _;
if ( _ == "lin" | _ == "linear" )
xscale=d3.scaleLinear()
if ( _ == "log" | _ =="logarithm" | _ =="logarithmic")
xscale=d3.scaleLog()
return chart;
};
return chart;
}
并用这个主要函数初始化:
data=`date,price
Jan 2000,1.46
Feb 2000,16.42
Mar 2000,14.58
Apr 2000,152.43
May 2000,1420.6
Jun 2000,1454.6
Jul 2000,1430.83
Aug 2000,1517.68
Sep 2000,1436.51`
data=d3.csvParse(data)
d3.select("body")
.append("figure")
.datum(data)
.call(scatter
.x("price")
)
它显示了轴,但不幸的是,以下更新代码不起作用:
d3.select("#linlog").on("change", function(){
var l=d3.select(this).property("checked")
var a;
l ? a=scatter.xscale("lin") : a=scatter.xscale("log")
d3.select("figure")
.call(a)
})
有什么问题?
你差不多明白了,主要的问题是在你的 xscale 函数中你没有 return 你的新比例尺。
chart.xscale = function(_) {
//...
return chart; // returning the chart object :(
}
让我们改变一下:
chart.xscale = function(_) {
if (!arguments.length) return xscale;
xscale = _;
if (_ === "lin" | _ === "linear") {
xscale=d3.scaleLinear();
}
if (_ === "log" | _ === "logarithm" | _ === "logarithmic") {
xscale = d3.scaleLog();
}
return xscale;
};
由于我们正在调用一个新的比例,我们需要配置新的范围和域值,让我们添加:
chart.xscale = function(_) {
if (!arguments.length) return xscale;
xscale = _;
if (_ === "lin" | _ === "linear") {
xscale = d3.scaleLinear();
}
if (_ === "log" | _ === "logarithm" | _ === "logarithmic") {
xscale = d3.scaleLog();
}
var width = w - margin.left - margin.right;
var xrange = [0, width];
xscale.range(xrange);
var xdomain = d3.extent(data, function(d) {
return +d[x];
})
xscale.domain(xdomain).nice();
return xscale;
};
终于可以正确调用坐标轴函数了
d3.select("#linlog").on("change", function() {
var l = d3.select(this).property("checked")
var a;
l ? a = scatter.xscale("lin") : a = scatter.xscale("log");
var axis = d3.axisBottom().scale(a);
axis.ticks(5);
d3.selectAll("g .x.axis")
.call(axis)
})
工作 jsfiddle:https://jsfiddle.net/6o4qu6jh/2/