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 将全局声明并可供所有代码访问。