score:0
I seem to have found a solution. After boning up on Javascript objects, I re-wrote my code to create and return a chart object that encapsulates the chart properties and methods. I can then call the render method in multiple chart objects to update them individually.
the new chart script:
function AgeChart(chartContainer, data) {
var chartObj = {
// public properties
xAxisLabel: "Alter",
yAxisLabel: "Anzahl",
margin: {top: 20, right: 10, bottom: 50, left: 60},
width: 0,
height: 0,
dummyData: 0,
sizeMax: 0,
countMax: 0,
// private properties
$chartGroup: 0,
$container: "",
$d: 0,
$svg: 0,
$x: d3.scaleBand()
.paddingInner(0.16)
.paddingOuter(0.1),
$xscale: d3.scaleBand()
.paddingInner(0.16)
.paddingOuter(0.1),
$y: d3.scaleLinear(),
$xAxis: 0,
$yAxis: 0,
// property sets
get data() { return this.$d; },
set data(d) {
this.$d = d;
this.dummyData = parseAgedData(d);
this.sizeMax = d.AgeDistribution.DataOwnerSizeMax;
for (var i = 0; i < this.dummyData.length; i++) {
if(this.dummyData[i].doCount > this.countMax) {
this.countMax = chartObj.dummyData[i].doCount;
}
};
this.$xscale.domain(this.dummyData.map(function(d) {
return d.label;
}));
this.$x.domain(this.dummyData.map(function(d,i) {
return i + 1;
}))
this.$y.domain([0, this.countMax]);
},
get container() { return this.$container },
set container(c) {
this.$container = c;
updateDimensions();
this.$svg = d3.select(this.container)
.append("svg")
.attr("id", chartObj.container.substring(1) + "Svg")
.classed("age-chart-canvas", true);
this.$chartGroup = this.$svg.append("g")
.attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")");
this.$yAxis = this.$chartGroup.append("g")
.attr("class", "axis axis--y");
this.$xAxis = this.$chartGroup.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + this.height + ")");
},
// methods
render: function() {
updateDimensions();
this.$xscale.rangeRound([0, this.width]);
this.$x.rangeRound([0, this.width]);
this.$y.rangeRound([this.height, 0]);
this.$yAxis.call(d3.axisLeft(this.$y))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text(function(d) {
return d;
});
var chartW = this.width;
d3.selectAll("g.axis--y g.tick line")
.attr("x1", function(d) {
return chartW;
});
this.$xAxis.call(d3.axisBottom(this.$xscale));
d3.selectAll("g.axis--x g.tick line")
.attr("y2", function(d, i) {
if(i%2 == 0)
return 6;
else
return 16;
})
.style("fill", "#bdbdbd");
d3.selectAll("g.axis--x g.tick text")
.attr("y", function(d, i) {
if(i%2 == 0)
return 9;
else
return 20;
});
}
};
chartObj.data = data;
chartObj.container = chartContainer;
chartObj.render();
function updateDimensions() {
var containerW = getDimension(chartObj.container, "width"),
containerH = getDimension(chartObj.container, "height");
chartObj.width = containerW - chartObj.margin.left -
chartObj.margin.right;
chartObj.height = containerH - chartObj.margin.top -
chartObj.margin.bottom;
};
return chartObj;
};
then on my page I call render() when the window is resized and all charts are updated independently...
<script type="text/javascript">
$(document).ready(function() {
var vData = ageDistributionData;
var dData = ageDistributionData;
var mData = ageDistributionData;
var vChart = AgeChart("#vChart", vData);
var dChart = new AgeChart("#dChart", dData);
var mChart = new AgeChart("#mChart", mData);
window.addEventListener("resize", function() {
vChart.render();
dChart.render();
mChart.render();
})
});
</script>
Any tips or suggestions are most welcome.
score:1
I was also stuck on this same issue. I know you found a solution but I thought I'd offer what I found in case it helps someone else who ends up at this page, since this question more accurately described my problem than anything else I've found.
My solution finally came from the following Stack Overflow post. The answer there explains that you need to add a namespace to the listener, otherwise the existing listener will be removed when a new one is added.
How to have multiple d3 window resize events
For this example, I had to change this code:
d3.select(window).on("resize", render);
to
var resizeId = "resize." + scope.chartId
d3.select(window).on(resizeId, render);
where scope.chartId was a unique id for each chart so that the listener was also unique and would not be removed when a new chart was added.
Source: stackoverflow.com
Related Query
- Multiple Responsive D3 Charts on same page reusing chart script
- multiple versions of a script on the same page (d3.js)
- D3 with AngularJs, Multiple charts on same page with different data based on common key
- want to generate multiple charts in d3 in same page for different data set
- placing multiple d3 charts on the same page but applying different styling
- d3.js - multiple charts on same page from different parts of same JSON object
- d3.js reusable charts on multiple elements in same page
- Multiple d3 charts on a page using the same Angular2 component
- d3 javascript display multiple charts on the same page
- Present same D3 Charts multiple times on a same html page
- Display multiple d3.js charts in a single html page
- dc.js add class to data points in multiple charts based on criteria from first chart
- Multiple instances of d3 force layout on the same page
- Implementing multiple D3 layout on same page
- D3 Reusable Chart Function Creating Multiple Charts
- Multiple multi-series d3 line charts on one page
- D3 Dimple - How to show multiple dimple charts on same page?
- How to update multiple pie charts in one page in D3?
- Align multiple y-axes on the same chart in Billboard.js
- Same X-axis Multiple Line Charts using d3
- Multiple d3 charts on a page with different (linear and log) axes
- Multiple D3 TreeMap on the same page with different div id's
- Two Donut Charts On The Same Page
- Issue with multiple d3 graphs on same page
- Updating bar chart in d3 generating multiple charts
- Creating Multiplie Pie Charts in a same page using d3 with JSON data
- With d3.js, how can I use the same script to create 3 charts with 3 datasources?
- Cannot have multiple charts in one HTML page - d3
- d3.js nvd3 issue: different charts on the same HTML page look the same (even though they have different IDs)
- Mouseover Line on multiple charts when hover on single chart using D3
More Query from same tag
- Get d3 v4 zoom and drag working together - simple example
- d3/cola programmatic node drag using initMouseEvent
- d3.js: Passing data from parent node to child node onclick event
- NVD3 line chart with vertical line
- D3 Tree layout: How to fill rectangles with text, but have them in uniform size?
- D3.js: Accessing Object Property inside Array for Creating Line Graph
- Techan.js - How to format time for weekly, monthly candlestick chart?
- ReferenceError - d3 is not defined
- Translate d3.js JavaScript function to CoffeeScript
- D3.js Gauge look like Telerik Radial Gauge
- How to create responsive svg using d3.js
- plotting json data in phant using d3 js
- D3 Slice array with from to values
- Ellipsis for long text
- How to scale year interval in D3 axis without changing columns
- Cocktail recipe Data Visualisation
- Horizontal Bar chart with vertical line is possible or not in D3
- D3 - axis only show values from 0-1
- Round images in D3.js Tree graph
- D3 multiseries chart drawing
- d3.select(#elementId) doesn't find a element
- Need some help on D3 pie layout adding line to label
- How to Select Element by Class and Retrieve its ID in D3
- Multiple mouseover events per element
- SVG with Horizontal Scrolling
- Restart D3 bar chart animation
- using dynamic list data in d3.js
- Accessibility: d3 brush/zoom can get focus and be controlled with keyboard
- Building JSON dynamically in D3 javascript
- Python csv to json (D3)