javascript — d3.js проблема масштабирования

d3.js проблема масштабирования

Я работаю над проектом django, в котором я интенсивно использую d3.js. У меня есть функция JavaScript, которая работает хорошо:

 function three_lines_pan_zoom_chart(id, data, options) { var plotChart = d3.select(id).classed('chart', true).append('svg') .attr('width', options.w   options.margin.left   options.margin.right) .attr('height', options.h   options.margin.top   options.margin.bottom) .append('g') .attr('transform', 'translate('   options.margin.left   ','   options.margin.top   ')'); var plotArea = plotChart.append('g') .attr('clip-path', 'url(#plot_Area_Clip)'); plotArea.append('clipPath') .attr('id', 'plot_Area_Clip') .append('rect') .attr({ width: options.w, height: options.h }); var navChart = d3.select(id).classed('complex_chart', true).append('svg') .classed('navigator', true) .attr('width', options.nav_w   options.margin.left   options.margin.right) .attr('height', options.nav_h   options.margin.top   options.margin.bottom) .append('g') .attr('transform', 'translate('   options.margin.left   ','   options.margin.top   ')'); var minN = d3.min(data, function (d) { return d.date; }).getTime(), maxN = d3.max(data, function (d) { return d.date; }).getTime(); var minDate = new Date(minN - 8.64e7), maxDate = new Date(maxN   8.64e7); var yMin = d3.min(data, function (d) { return Math.min(d.value, d.valueBchk, d.valueIdx); }), yMax = d3.max(data, function (d) { return Math.max(d.value, d.valueBchk, d.valueIdx); }); var xScale = d3.time.scale() .domain([minDate, maxDate]) .range([0, options.w]), yScale = d3.scale.linear() .domain([yMin, yMax]).nice() .range([options.h, 0]); var navXScale = d3.time.scale() .domain([minDate, maxDate]) .range([0, options.nav_w]), navYScale = d3.scale.linear() .domain([yMin, yMax]) .range([options.nav_h, 0]); var xAxis = d3.svg.axis() .scale(xScale) .orient("bottom") .ticks(5); var yAxis = d3.svg.axis() .scale(yScale) .orient("left"); plotChart.append('g') .attr('class', 'x axis') .style("fill", "#6C5373") .attr('transform', 'translate(0,'   options.h   ')') .call(xAxis); plotChart.append("text") // text label for the x axis .attr("transform", "translate("   (options.w / 2)   " ,"   (options.h   options.margin.bottom)   ")") .style("text-anchor", "middle") .text("Dates"); plotChart.append('g') .attr('class', 'y axis') .style("fill", "#6C5373") .call(yAxis); plotChart.append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .style("fill", "#6C5373") .attr("dy", ".71em") .style("text-anchor", "end") .text("Cumulative Returns"); var navXAxis = d3.svg.axis() .scale(navXScale) .orient('bottom'); navChart.append('g') .attr('class', 'x axis') .style("fill", "#6C5373") .attr('transform', 'translate(0,'   options.nav_h   ')') .call(navXAxis); var line = d3.svg.line() .x(function (d) { return xScale(d.date); }) .y(function (d) { return yScale(d.value); }); var line2 = d3.svg.line() .x(function (d) { return xScale(d.date); }) .y(function (d) { return yScale(d.valueBchk); }); var line3 = d3.svg.line() .x(function (d) { return xScale(d.date); }) .y(function (d) { return yScale(d.valueIdx); }); plotArea.append('g') .attr('class', 'line') .datum(data) .call(line); plotArea.append('g') .attr('class', 'line') .datum(data) .call(line2); plotArea.append('g') .attr('class', 'line') .datum(data) .call(line3); var navData = d3.svg.area() .x(function (d) { return navXScale(d.date); }) .y0(options.nav_h) .y1(function (d) { return navYScale(d.value); }); var navLine = d3.svg.line() .x(function (d) { return navXScale(d.date); }) .y(function (d) { return navYScale(d.value); }); plotArea.append("path") .datum(data) .attr("class", "FdLine") .style("stroke", "#996A4E") .attr("d", line); plotChart.append("text") .attr("transform", "translate("   (options.w   3)   ","   yScale(data[data.length - 1].value)   ")") .attr("dy", ".35em") .style("fill", "#996A4E") .attr("text-anchor", "start") .attr("class", "legFD") .text(data[0].name); plotArea.append("path") .datum(data) .attr("class", "Bchkline") .style("stroke", "#45538C") .attr("d", line2); plotChart.append("text") .attr("transform", "translate("   (options.w   3)   ","   yScale(data[data.length - 1].valueBchk)   ")") .attr("dy", ".35em") .style("fill", "#45538C") .attr("text-anchor", "start") .attr("class", "legBchk") .text(data[0].bchk_name); plotArea.append("path") .datum(data) .attr("class", "Idxline") .style("stroke", "D994B0") .attr("d", line3); plotChart.append("text") .attr("transform", "translate("   (options.w   3)   ","   yScale(data[data.length - 1].valueIdx)   ")") .attr("dy", ".35em") .style("fill", "D994B0") .attr("text-anchor", "start") .attr("class", "legIdx") .text(data[0].idx_name); navChart.append('path') .attr('class', 'data') .attr('d', navData(data)); navChart.append('path') .attr('class', 'line') .attr('d', navLine(data)); var viewport = d3.svg.brush() .x(navXScale) .on("brush", function () { xScale.domain(viewport.empty() ? navXScale.domain() : viewport.extent()); redrawChart(data); }); var zoom = d3.behavior.zoom() .x(xScale) .on('zoom', function () { if (xScale.domain()[0] {amp}lt; minDate) { var x = zoom.translate()[0] - xScale(minDate)   xScale.range()[0]; zoom.translate([x, 0]); } else if (xScale.domain()[1] {amp}gt; maxDate) { var x = zoom.translate()[0] - xScale(maxDate)   xScale.range()[1]; zoom.translate([x, 0]); } redrawChart(data); updateViewportFromChart(); }); navChart.append("g") .attr("class", "viewport") .call(viewport) .selectAll("rect") .attr("height", options.nav_h); var overlay = d3.svg.area() .x(function (d) { return xScale(d.date); }) .y0(0) .y1(options.h); plotArea.append('path') .attr('class', 'overlay') .attr('d', overlay(data)) .call(zoom); viewport.on("brushend", function () { updateZoomFromChart(); }); xScale.domain([ data[0].date, data[data.length - 1].date ]); function redrawChart(data) { var posXScale = xScale.domain()[1]; var myMth = posXScale.getMonth(); var myYear = posXScale.getFullYear(); //data.setMonths(data.getMonth()   1, 0, 23, 59, 59, 0) //var dateEom = getLastDateOfMonth(1999, 8); var myDates = data.map(function(b) {return b.date;}); //var position = data.indexOf(dateEom); var isDateEom = false; var position = myDates.length-1; for (var i = 0; i {amp}lt; myDates.length; i  ) { if (myDates[i].getMonth() == myMth {amp}amp;{amp}amp; myDates[i].getFullYear() == myYear) { isDateEom = true; position = i; break; } } plotChart.select(".FdLine").attr("d", line); plotChart.select(".Bchkline").attr("d", line2); plotChart.select(".Idxline").attr("d", line3); plotChart.select(".legFD").attr("transform", "translate("   (options.w   3)   ","   yScale(data[position].value)   ")"); plotChart.select(".legBchk").attr("transform", "translate("   (options.w   3)   ","   yScale(data[position].valueBchk)   ")"); plotChart.select(".legIdx").attr("transform", "translate("   (options.w   3)   ","   yScale(data[position].valueIdx)   ")"); plotChart.select('.x.axis').call(xAxis); } function updateViewportFromChart() { if ((xScale.domain()[0] {amp}lt;= minDate) {amp}amp;{amp}amp; (xScale.domain()[1] {amp}gt;= maxDate)) { viewport.clear(); } else { viewport.extent(xScale.domain()); } navChart.select('.viewport').call(viewport); } function updateZoomFromChart() { zoom.x(xScale); var fullDomain = maxDate - minDate, currentDomain = xScale.domain()[1] - xScale.domain()[0]; var minScale = currentDomain / fullDomain, maxScale = minScale * 20; zoom.scaleExtent([minScale, maxScale]); } function getLastDateOfMonth(Year, Month) { return (new Date((new Date(Year, Month   1, 1)) - 1)); } redrawChart(data); updateZoomFromChart(); updateViewportFromChart(); 

Я вызываю эту функцию из HTML-скрипта:

 {% load staticfiles %} {% load static %} {amp}lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"{amp}gt;{amp}lt;/script{amp}gt; {amp}lt;script src="https://d3js.org/d3.v3.js"{amp}gt;{amp}lt;/script{amp}gt; {amp}lt;script type="text/javascript" src="{% static "fund/charts.js" %}"{amp}gt;{amp}lt;/script{amp}gt; {amp}lt;script{amp}gt; var width_init_pzc = $("{{ id_chart }}").width(), margin_pzc = { top: (width_init_pzc*30)/1000, right: (width_init_pzc*140)/1000, bottom: (width_init_pzc*50)/1000, left: (width_init_pzc*120)/1000 }, width_pzc = width_init_pzc - margin_pzc.left - margin_pzc.right, height_pzc = 500 - margin_pzc.top - margin_pzc.bottom, height_pzc2 = $("{{ id_chart }}").height(); var navWidth_init_pzc = width_init_pzc, navHeight_init_pzc = 100 - margin_pzc.top - margin_pzc.bottom; var formatDate = d3.time.format("%Y-%m-%d").parse; var palette_color_pzc= ["#6C5373", "#8BADD9", "#B6D6F2", "#45788C", "#6E87F2", "996A4E", "BF7761", "735360", "D994B0", "6C5373", "7F805E", "A6A27A", "48BDCC", "FFC956", "#F2F2F2"]; var chartOptions_pzc = { w: width_pzc, h: height_pzc, margin: margin_pzc, paletteColor: palette_color_pzc, nav_w: navWidth_init_pzc, nav_h: navHeight_init_pzc }; d3.json("{% url "fund:data_cumulative_returns_chart" fund %}", function (error, data) { if (error) throw error; console.log(data) data.forEach(function (d) { d.date = formatDate(d.date); d.value =  d.value; d.valueBchk =  d.valueBchk; d.valueIdx =  d.valueIdx; }) //Call function to draw the multiple lines chart three_lines_pan_zoom_chart("{{ id_chart }}", data, chartOptions_pzc); }); 

Я создал другую функцию HTML, которая вызвала ту же функцию javascript:

 {% load staticfiles %} {amp}lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"{amp}gt;{amp}lt;/script{amp}gt; {amp}lt;script src="https://d3js.org/d3.v3.js"{amp}gt;{amp}lt;/script{amp}gt; {amp}lt;script type="text/javascript" src="{% static "fund/charts.js" %}"{amp}gt;{amp}lt;/script{amp}gt; {amp}lt;script{amp}gt; var width_init_ts_pf = $("#vami_portfolio").width(), margin_ts_pf = { top: (width_init_ts_pf*30)/1000, right: (width_init_ts_pf*50)/1000, bottom: (width_init_ts_pf*50)/1000, left: (width_init_ts_pf*50)/1000 }, width_ts_pf = width_init_ts_pf - margin_ts_pf.left - margin_ts_pf.right, height_ts_pf = 500 - margin_ts_pf.top - margin_ts_pf.bottom, height2 = $("#vami_portfolio").height(); var navWidth_ts_pf = width_ts_pf, navHeight_ts_pf = 100 - margin_ts_pf.top - margin_ts_pf.bottom; var formatDate = d3.time.format("%Y-%m-%d").parse; var palette_color_ts_pf = ["#6C5373", "#8BADD9", "#B6D6F2", "#45788C", "#6E87F2", "996A4E", "BF7761", "735360", "D994B0", "6C5373", "7F805E", "A6A27A", "48BDCC", "FFC956", "#F2F2F2"]; var chartOptions_ts_pf = { w: width_ts_pf, h: height_ts_pf, margin: margin_ts_pf, paletteColor: palette_color_ts_pf, nav_w: navWidth_ts_pf, nav_h: navHeight_ts_pf }; d3.json("{% url "portfolio:data_cumulative_returns" portfolio type %}", function (error, data) { if (error) throw error; console.log(data) data.forEach(function (d) { d.date = formatDate(d.date); d.value =  d.value; d.valueBchk =  d.valueBchk; d.valueIdx =  d.valueIdx; }); //Call function to draw the multiple lines chart three_lines_pan_zoom_chart("{{ id_chart }}", data, chartOptions_ts_pf); }); {amp}lt;/script{amp}gt; 

С момента создания второго HTML-скрипта функция масштабирования больше не работает для первого графика. Кроме того, когда я попытался удалить второй HTML-скрипт, я не восстановил функциональность панорамирования. Можно ли использовать функцию масштабирования панорамирования для нескольких SVG? У кого-то есть идея, почему pan-zoom работает только для второго скрипта и почему, когда я удалил второй HTML-файл, я не восстановил эту функциональность?

Большое спасибо заранее за вашу помощь

Понравилась статья? Поделиться с друзьями:
JavaScript & TypeScript
Adblock
detector