Могу ли я определить максимальное количество тиков по оси d3.js?

Передайте аргументы перед -jar. Если вы передадите их после файла jar, они интерпретируются как параметры командной строки и передаются в String[] args в main. Например,

java -Denviroment=dev -jar myjar.jar 
1
задан AJPerez 27 March 2019 в 11:35
поделиться

1 ответ

У меня есть первое «рабочее» решение ... и оно уродливее, чем я думал, это будет:

const chart = dc.seriesChart('#myChart')
    // ...
    .x(d3.scaleTime())
    .elasticY(true)
    .elasticX(true)
    .on('renderlet', updateTicks);
    .xAxis()
        .tickFormat(d3.timeFormat('%Y-%m-%d'))
        .ticks(10); // We set 10 ticks by default
chart.render();

// Needed to prevent infinite loops...
let redrawing = false;

function updateTicks(chart) {
    if (redrawing) {
        redrawing = false;
    } else {
        const days = (chart.xAxisMax() - chart.xAxisMin()) / 86400000;
        if (days < 10) {
            chart.xAxis().ticks(d3.timeDay);
        } else {
            chart.xAxis().ticks(10);
        }
        redrawing = true;
        chart.redraw();
    }
}

xAxisMin() и xAxisMax() значения не рассчитываются, пока диаграмма уже рендеринг или перерисовка, поэтому я должен использовать событие renderlet вместо preRedraw. А поскольку график уже нарисован, любое изменение, которое я внесу в ось, будет неэффективным до следующего перерисовки ... поэтому я вынужден сам принудить его (и предотвратить бесконечный цикл, потому что мой перерисовка вызовет новое событие renderlet ). [1 110]

Это не только некрасивый код, осевой переход фактически виден на графике. Я мог бы избежать этого, используя вместо этого событие pretransition, как указал Гордон. Или путем вычисления минимальных и максимальных значений для события preRender / preRedraw непосредственно из группы Crossfilter, но это начинает ощущаться как огромное излишество.


Вот работающее, но все еще уродливое решение, вычисляющее сам минимум и максимум:

const chart = dc.seriesChart('#myChart')
    // ...
    .x(d3.scaleTime())
    .elasticY(true)
    .elasticX(true)
    .on('preRender', updateTicks),
    .on('preRedraw', updateTicks);
    .xAxis().tickFormat(d3.timeFormat('%Y-%m-%d'));
chart.render();

function updateTicks(chart) {
    const range = chart.group().all().reduce((accum, d) => minMax(d.key.date, accum), {});
    const days = 1 + ((new Date(range.max) - new Date(range.min)) / 86400000);
    if (days <= 7) {
        chart.xAxis().ticks(d3.timeDay);
    } else if (days <= 30) {
        chart.xAxis().ticks(d3.timeMonday);
    } else {
        chart.xAxis().ticks(d3.timeMonth);
    }
}

function minMax(val, obj) {
    if ((obj.min === undefined) || (val < obj.min)) {
        obj.min = val;
    }
    if ((obj.max === undefined) || (val > obj.max)) {
        obj.max = val;
    }
    return obj;
}

Сам по себе не уродливый код, это просто раздражает - каждый массив обходит каждый массив данных время, когда я перерисовываю диаграмму, только для того, чтобы найти минимальное и максимальное значения, которые все равно будут снова вычислены dc / crossfilter / d3.

0
ответ дан AJPerez 27 March 2019 в 11:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: