dc.js 如何在 renderAll 之后更新 yscale
dc.js How to update yscale after a renderAll
我有一个调用 Serieschart 的脚本。我已将图表与三个按钮链接起来,这些按钮加载不同的数据集并相应地更新图表(请参阅下面的代码)。每次选择另一个数据集时,我都想重新定义 yscale。我不知道该怎么做,因为我无法访问按钮功能中的图表对象。非常感谢您的帮助。
<div class="row top-buffer">
<div class="col-sm-4">
<button class="btn" onclick="button1()">1</button>
</div>
<div class="col-sm-4">
<button class="btn" onclick="button2()">2</button>
</div>
<div class="col-sm-4">
<button class="btn" onclick="button3()">3</button>
</div>
</div>
<div class="row top-buffer">
<div id="chart" class="col-sm-12">
<h6 id="title">{{ title }}</h6>
<span class='reset'>
Current filter: <span class='filter'></span>
</span>
<a class='reset'
href='javascript:dc.filterAll();dc.redrawAll();'
>reset</a>
</div>
</div>
<script>
/**********************************
* Step0: template set up *
**********************************/
var width_block= Math.max(1100, $("{{ id_chart }}").width());
var palette_color_block = ["#6c5373", "#8badd9", "#b6d6f2", "#45788c", "#6E87F2", "#996A4E", "#BF7761",
"#735360", "#D994B0", "#6C5373", "#7F805E", "#A6A27A", "#48BDCC", "#FFC956", "#f2f2f2"];
var shades_and_tints = ["#305462", "#376070", "#3e6c7e", "#45788c", "#578597", "#6a93a3", "#7ca0ae",
"#8faeba", "#a2bbc5", "#b4c9d1", "#c7d6dc", "#d9e4e8"];
var complementary_color = ["#45788c", "#8c5945"];
var triadic_color = ["#788c45", "#45788c", "#8c4578"];
var myChart = new dc.SeriesChart("#chart");
/**********************************
* Step1: Load data from json file *
**********************************/
d3.json("{% url my_url %}").then(function(data){
const dateFormatSpecifier = "%Y-%m-%d";
const dateFormat = d3.timeFormat(dateFormatSpecifier);
const dateFormatParser = d3.timeParse(dateFormatSpecifier);
const numberFormat = d3.format('.2f');
data.forEach(function(d) {
d.dd = dateFormatParser(d.date);
d.month = d3.timeMonth(d.dd); // pre-calculate month for better performance
d.vami = +d.vami;
});
const minY = d3.min(data, function(d) { return d.vami; }),
maxY = d3.max(data, function(d) { return d.vami; });
/******************************************************
* Step2: Create the dc.js chart objects & ling to div *
******************************************************/
/************************************************
* Step3: Run the data through crossfilter *
************************************************/
ndx = crossfilter(data); // Gets our 'facts' into crossfilter
/******************************************************
* Step4: Create the Dimensions *
* A dimension is something to group or filter by. *
* Crossfilter can filter by exact value, or by range. *
******************************************************/
const dateDimension = ndx.dimension(d => d.dd);
const nameMonthDimension = ndx.dimension(function(d) {return [d.name, d.month]; });
const nameMonthGroup = nameMonthDimension .group().reduceSum(function(d) { return +d.vami; });
let xScale = d3.scaleTime().domain([dateDimension .bottom(1)[0].dd, dateDimension .top(1)[0].dd])
let yScale = d3.scaleLinear().domain([minY, maxY])
/***************************************
* Step5: Create the Visualisations *
***************************************/
myChart
.width(width_block)
.height(width_block/3)
.transitionDuration(500)
.margins({top: width_block/30, right: width_block/20, bottom: width_block/40, left:
width_block/25})
.chart(function(c) { return new dc.LineChart(c); })
.ordinalColors(palette_color_block)
.mouseZoomable(true)
.brushOn(false)
.clipPadding(10)
.elasticY(false)
.x(xScale)
.y(yScale)
.round(d3.timeMonth.round)
.xUnits(d3.timeMonths)
.dimension(nameMonthDimension )
.group(nameMonthGroup )
.seriesAccessor(function(d) {return d.key[0];})
.keyAccessor(function(d) {return +d.key[1];})
.valueAccessor(function(d) {return +d.value;})
.legend(dc.legend().x(60).y(60).itemHeight(13).gap(5).horizontal(1).legendWidth(200).itemWidth(200));
/****************************
* Step6: Render the Charts *
****************************/
dc.renderAll();
});
function load_button(file) {
return function load_it() {
d3.json(file).then(function(new_data){
const dateFormatSpecifier = "%Y-%m-%d";
const dateFormat = d3.timeFormat(dateFormatSpecifier);
const dateFormatParser = d3.timeParse(dateFormatSpecifier);
const numberFormat = d3.format('.2f');
new_data.forEach(function(d) {
d.dd = dateFormatParser(d.date);
d.month = d3.timeMonth(d.dd); // pre-calculate month for better performance
d.vami = +d.vami;
});
const minY = d3.min(new_data, function(d) { return d.vami; }),
maxY = d3.max(new_data, function(d) { return d.vami; });
let yScale = d3.scaleLinear().domain([minY, maxY])
ndx.remove(() => true);
ndx.add(new_data);
myChart.y(yScale);
dc.redrawAll();
});
};
}
var button1 = load_button("{% url my_url %}"),
button2 = load_button("{% url my_url2 %}"),
button3 = load_button("{% url my_url3 %}");
</script>
只是在哪里声明的问题myChart
。
许多 dc.js 示例在调用之前声明变量 d3.json
:
var myChart;
d3.json("{% url my_url %}").then(function(data){
// ...
myChart = new dc.SeriesChart("#chart");
或者,在调用d3.json
之前移动初始化也无妨:
var myChart = new dc.SeriesChart("#chart");
d3.json("{% url my_url %}").then(function(data){
// ...
现在 myChart
将全局声明并可供所有代码访问。
我有一个调用 Serieschart 的脚本。我已将图表与三个按钮链接起来,这些按钮加载不同的数据集并相应地更新图表(请参阅下面的代码)。每次选择另一个数据集时,我都想重新定义 yscale。我不知道该怎么做,因为我无法访问按钮功能中的图表对象。非常感谢您的帮助。
<div class="row top-buffer">
<div class="col-sm-4">
<button class="btn" onclick="button1()">1</button>
</div>
<div class="col-sm-4">
<button class="btn" onclick="button2()">2</button>
</div>
<div class="col-sm-4">
<button class="btn" onclick="button3()">3</button>
</div>
</div>
<div class="row top-buffer">
<div id="chart" class="col-sm-12">
<h6 id="title">{{ title }}</h6>
<span class='reset'>
Current filter: <span class='filter'></span>
</span>
<a class='reset'
href='javascript:dc.filterAll();dc.redrawAll();'
>reset</a>
</div>
</div>
<script>
/**********************************
* Step0: template set up *
**********************************/
var width_block= Math.max(1100, $("{{ id_chart }}").width());
var palette_color_block = ["#6c5373", "#8badd9", "#b6d6f2", "#45788c", "#6E87F2", "#996A4E", "#BF7761",
"#735360", "#D994B0", "#6C5373", "#7F805E", "#A6A27A", "#48BDCC", "#FFC956", "#f2f2f2"];
var shades_and_tints = ["#305462", "#376070", "#3e6c7e", "#45788c", "#578597", "#6a93a3", "#7ca0ae",
"#8faeba", "#a2bbc5", "#b4c9d1", "#c7d6dc", "#d9e4e8"];
var complementary_color = ["#45788c", "#8c5945"];
var triadic_color = ["#788c45", "#45788c", "#8c4578"];
var myChart = new dc.SeriesChart("#chart");
/**********************************
* Step1: Load data from json file *
**********************************/
d3.json("{% url my_url %}").then(function(data){
const dateFormatSpecifier = "%Y-%m-%d";
const dateFormat = d3.timeFormat(dateFormatSpecifier);
const dateFormatParser = d3.timeParse(dateFormatSpecifier);
const numberFormat = d3.format('.2f');
data.forEach(function(d) {
d.dd = dateFormatParser(d.date);
d.month = d3.timeMonth(d.dd); // pre-calculate month for better performance
d.vami = +d.vami;
});
const minY = d3.min(data, function(d) { return d.vami; }),
maxY = d3.max(data, function(d) { return d.vami; });
/******************************************************
* Step2: Create the dc.js chart objects & ling to div *
******************************************************/
/************************************************
* Step3: Run the data through crossfilter *
************************************************/
ndx = crossfilter(data); // Gets our 'facts' into crossfilter
/******************************************************
* Step4: Create the Dimensions *
* A dimension is something to group or filter by. *
* Crossfilter can filter by exact value, or by range. *
******************************************************/
const dateDimension = ndx.dimension(d => d.dd);
const nameMonthDimension = ndx.dimension(function(d) {return [d.name, d.month]; });
const nameMonthGroup = nameMonthDimension .group().reduceSum(function(d) { return +d.vami; });
let xScale = d3.scaleTime().domain([dateDimension .bottom(1)[0].dd, dateDimension .top(1)[0].dd])
let yScale = d3.scaleLinear().domain([minY, maxY])
/***************************************
* Step5: Create the Visualisations *
***************************************/
myChart
.width(width_block)
.height(width_block/3)
.transitionDuration(500)
.margins({top: width_block/30, right: width_block/20, bottom: width_block/40, left:
width_block/25})
.chart(function(c) { return new dc.LineChart(c); })
.ordinalColors(palette_color_block)
.mouseZoomable(true)
.brushOn(false)
.clipPadding(10)
.elasticY(false)
.x(xScale)
.y(yScale)
.round(d3.timeMonth.round)
.xUnits(d3.timeMonths)
.dimension(nameMonthDimension )
.group(nameMonthGroup )
.seriesAccessor(function(d) {return d.key[0];})
.keyAccessor(function(d) {return +d.key[1];})
.valueAccessor(function(d) {return +d.value;})
.legend(dc.legend().x(60).y(60).itemHeight(13).gap(5).horizontal(1).legendWidth(200).itemWidth(200));
/****************************
* Step6: Render the Charts *
****************************/
dc.renderAll();
});
function load_button(file) {
return function load_it() {
d3.json(file).then(function(new_data){
const dateFormatSpecifier = "%Y-%m-%d";
const dateFormat = d3.timeFormat(dateFormatSpecifier);
const dateFormatParser = d3.timeParse(dateFormatSpecifier);
const numberFormat = d3.format('.2f');
new_data.forEach(function(d) {
d.dd = dateFormatParser(d.date);
d.month = d3.timeMonth(d.dd); // pre-calculate month for better performance
d.vami = +d.vami;
});
const minY = d3.min(new_data, function(d) { return d.vami; }),
maxY = d3.max(new_data, function(d) { return d.vami; });
let yScale = d3.scaleLinear().domain([minY, maxY])
ndx.remove(() => true);
ndx.add(new_data);
myChart.y(yScale);
dc.redrawAll();
});
};
}
var button1 = load_button("{% url my_url %}"),
button2 = load_button("{% url my_url2 %}"),
button3 = load_button("{% url my_url3 %}");
</script>
只是在哪里声明的问题myChart
。
许多 dc.js 示例在调用之前声明变量 d3.json
:
var myChart;
d3.json("{% url my_url %}").then(function(data){
// ...
myChart = new dc.SeriesChart("#chart");
或者,在调用d3.json
之前移动初始化也无妨:
var myChart = new dc.SeriesChart("#chart");
d3.json("{% url my_url %}").then(function(data){
// ...
现在 myChart
将全局声明并可供所有代码访问。