Что дано
Имеется сайт, на который с помощью библиотеки d3.js подгружается график.
В коде имеется div с id chart, который используется скриптом для встраивания данных в него
...
<div id="chart">
<svg width="100" height="100"></svg>
</div>
...
После загрузки документа подгружаю скрипт.
...
</body>
<script src="chart.js"></script>
...
Скрипт выглядит таким образом:
var Chart = (function(window,d3) {
var svg, x, y, data1, data2, USDdata1, USDdata2, xAxis, yAxis, dim, chartWrapper, line, path, margin = {}, width, height;
var label;
var breakPointScreen = 1280;
var breakPointTablet = 769;
var breakPointPhone = 401;
// Цвета
var colorFact = 'rgb(31, 119, 180)';
var colorCalc = 'rgb(255, 127, 14)';
// ЛЕГЕНДА
// Сдвиг для легенды
var legendY, legendX;
var legendRectY = 20;
var legendLabelY = 20;
var rect1, rect2, label1, label2;
// Загрузка данных из файлов
d3.csv(prefix + 'data.csv', function(error1, csv1) {
d3.csv(prefix + 'data2.csv', function(error2, csv2){
init(csv1, csv2);
});
});
d3.csv('2data.csv', function(error1, csv1) {
USDdata1 = csv1;
});
d3.csv('2data2.csv', function(error2, csv2){
USDdata2 = csv2;
// stop the loader
spinner.stop();
});
//called once the data is loaded
function init(csv1, csv2) {
data1 = csv1;
data2 = csv2;
//initialize scales
xExtent = d3.extent(data1.concat(data2), function(d,i) { return new Date(d.date) });
yExtent = d3.extent(data1.concat(data2), function(d,i) { return d.value });
// Продлеваем график на 15 дней назад и 15 дней вперед, чтобы было нагляднее
var first = new Date(xExtent[0]),
last = new Date(xExtent[1]);
xExtent[0] = new Date(first.setDate(first.getDate() - 30));
xExtent[1] = new Date(last.setDate(first.getDate() + 60));
x = d3.time.scale().domain(xExtent);
y = d3.scale.linear().domain([10000, 150000]);
//initialize axis
xAxis = d3.svg.axis().orient('bottom');
yAxis = d3.svg.axis().orient('left');
//the path generator for the line chart
line = d3.svg.line()
.x(function(d) { return x(new Date(d.date)) })
.y(function(d) { return y(d.value) });
// .interpolate("basis");
//initialize svg
svg = d3.select('#chart').select('svg');
chartWrapper = svg.append('g');
path = chartWrapper.append('path').datum(data1).classed('line', true);
path2 = chartWrapper.append('path').datum(data2).classed('line2', true);
// Перемещаем в правый верхний угол
legend = chartWrapper.append('g')
.attr("transform", "translate(" + legendX + "," + legendY + ")");
rect1 = legend.append('rect');
rect2 = legend.append('rect');
label1 = legend.append('text');
label2 = legend.append('text');
chartWrapper.append('g').classed('x axis', true);
chartWrapper.append('g').classed('y axis', true);
//render the chart
render();
}
// Обёртка, чтобы задерживать вызовы, а не каждую мс вызывать
function throttle(func, ms) {
var isThrottled = false,
savedArgs,
savedThis;
function wrapper() {
if (isThrottled) { // (2)
savedArgs = arguments;
savedThis = this;
return;
}
func.apply(this, arguments); // (1)
isThrottled = true;
setTimeout(function() {
isThrottled = false; // (3)
if (savedArgs) {
wrapper.apply(savedThis, savedArgs);
savedArgs = savedThis = null;
}
}, ms);
}
return wrapper;
}
// Отрисовка
function render() {
//get dimensions based on window size
updateDimensions(document.documentElement);
//update x and y scales to new dimensions
x.range([0, width]);
y.range([height, 0]);
//update svg elements to new dimensions
svg
.attr('width', width + margin.right + margin.left)
.attr('height', height + margin.top + margin.bottom);
chartWrapper.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// Меняем количество черточек на оси Х
if (window.innerWidth < breakPointPhone) {
xAxis.ticks(d3.time.month, 4);
}
else if(window.innerWidth < breakPointScreen) {
xAxis.ticks(d3.time.month, 3);
}
else
{
xAxis.ticks(d3.time.month, 2);
}
yAxis.ticks(20);
//update the axis and line
xAxis.scale(x);
yAxis.scale(y);
// yAxis.scale(y).orient(window.innerWidth < breakPointTablet ? 'right' : 'left');
svg.select('.x.axis')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
svg.select('.y.axis')
.call(yAxis);
// Добавляем графики
path.attr('d', line)
.attr('stroke', colorFact)
.attr('stroke-width', 2)
.attr('fill', 'none');
path2.attr('d', line)
.attr('stroke', colorCalc)
.attr('stroke-width', 2)
.attr('fill', 'none');
// Легенда
legend.attr("transform", "translate(" + legendX + "," + legendY + ")");
rect1.remove();
rect2.remove();
label1.remove();
label2.remove();
rect1 = legend.append('rect');
rect2 = legend.append('rect');
label1 = legend.append('text');
label2 = legend.append('text');
// Добавляем квадратики
rect1
.attr('y', 0)
.attr('width', '10')
.attr('height', '10')
.attr('rx', '3')
.attr('ry', '3')
.attr('fill', colorFact);
rect2
.attr('y', legendRectY)
.attr('width', '10')
.attr('height', '10')
.attr('rx', '3')
.attr('ry', '3')
.attr('fill', colorCalc);
// Добавляем надписи
label1
.attr("transform", "translate(" + 15 + "," + 6 + ")")
.attr('width', '50')
.attr("dy", ".35em")
.attr("class", "legend")
.attr("text-anchor", "start")
.style("fill", "#9a9a9a")
.text("Факт. значения");
label2
.attr("transform", "translate(" + 15 + "," + (6 + legendLabelY) + ")")
.attr("dy", ".35em")
.attr("class", "legend")
.attr("text-anchor", "start")
.style("fill", "#9a9a9a")
.text("Расч. значения");
}
// Обновляем размеры
function updateDimensions(win) {
// Изменение разрешения
}
return {
render : render,
changeValue : throttle(changeValue, 10),
toggleUSD : toggleUSD
}
})(window,d3);
window.addEventListener('resize', Chart.render);
Все работает отлично для одной страницы.
Проблема заключается в чем:
Сверху имеется меню вида
<ul id="nav">
<li><a href="graph.html" class="active">Текущий график</a></li>
<li><a href="changesgraph.html">Новый график</a></li>
...
</ul>
При переходе по ссылке, график
отказывается подгружаться.
Что пробовал
Пробовал заменить имя объекта
Chart на
NewChart и само название скрипта с
chart.js на
changeschart.js, и соот-но все вызовы. Не помогло.
Пробовал отследить загружаемые данные через инструменты разработчика, не увидел там, чтобы он подгружал новые скрипты.
Попробовал сделать изощрённую конструкцию вида
<ul id="nav">
<li><a href="graph.html" class="active">Текущий график</a></li>
<li><a href="changesgraph.html" onclick="window.location.href = '/changesgraph.html';">Новый график</a></li>
...
</ul>
Такой подход заработал, потом полез проверять с мобильного браузера -
опять отваливается. Просто не отрисовывает ничего и все.
Затем вернулся опять к старому меню без
onclick, оно работает только с мобильных.
Не могу понять, что за мистика. Есть подозрения, что это браузер как-то хитро обновляет страницу без подгрузки данных, но не получилось найти информацию про это.
Браузер
Использовал Yandex.Browser с ноутбука и телефона. А так же в эмуляторе из инструментов разработчика заходил под Safari мобильным.
Уважаемые знатоки, вопрос
Как заставить работать графики на обоих страницах?