我在codepen中有这个例子,但是希望在d3 v5中实现相同的功能。 https://codepen.io/manglass/pen/MvLBRz
我正在使用打字稿,我的代码在g.selectall('svg')下面打破了。 如果我有d3.select(g).selectAll('svg')。data(data).enter()。它抛出this.querySelectorAll不是函数
有人可以帮我吗?
setTimeout(function () {
(function timelines() {
const appendTimeAxis = function (g, xAxis, yPosition) {
const axis = g.append('g')
.attr('class', 'axis')
.attr('transform', 'translate(' + 0 + ',' + yPosition + ')')
.call(xAxis);
};
const appendLabel = function (gParent, yAxisMapping, index, hasLabel, datum) {
const fullItemHeight = itemHeight + itemMargin;
const rowsDown = margin.top + (fullItemHeight / 2) + fullItemHeight * (yAxisMapping[index] || 1);
gParent.append('text')
.attr('class', 'timeline-label')
.attr('transform', 'translate(' + labelMargin + ',' + rowsDown + ')')
.text(hasLabel ? labelFunction(datum.label) : datum.id)
.on('click', function (d, i) {// click(d, index, datum);
});
};
(function timeline(gParent) {
const temp: any = d3.select('#timeline3');
console.log('d3 selector');
console.log(temp);
// gParent = temp._groups[0][0].firstChild;
gParent = d3.select(temp._groups[0][0].firstChild);
console.log('gParent');
console.log(gParent);
let g = temp._groups[0][0].firstChild.firstChild.firstChild;
// const g = gParent.append('g');
console.log('g');
console.log(g);
const gParentSize = temp._groups[0][0].firstChild.getBoundingClientRect();
let gParentItem = temp._groups[0][0].firstChild;
gParentItem = d3.select(gParentItem);
console.log(d3.select(gParentItem));
const yAxisMapping = {};
let maxStack = 1,
minTime = 0,
maxTime = 0;
setWidth();
if (stacked || ending === 0 || beginning === 0) {
g = d3.select(g);
input = g._groups[0][0].__data__;
g = g._groups;
console.log(g);
g.forEach(function (d, i) {
console.log('d');
d = input;
console.log(d);
d.forEach(function (datum, index) {
console.log(datum);
console.log(index);
// create y mapping for stacked graph
if (stacked && Object.keys(yAxisMapping).indexOf(index) == -1) {
yAxisMapping[index] = maxStack;
maxStack++;
}
// figure out beginning and ending times if they are unspecified
datum.times.forEach(function (time, i) {
if (beginning === 0) {
if (time.starting_time < minTime || (minTime === 0 && timeIsRelative === false)) {
minTime = time.starting_time;
}
}
if (ending === 0) {
if (time.ending_time > maxTime) {
maxTime = time.ending_time;
}
}
});
});
});
if (ending === 0) {
ending = maxTime;
}
if (beginning === 0) {
beginning = minTime;
}
}
const scaleFactor = (1 / (ending - beginning)) * (width - margin.left - margin.right);
// draw the axis
const xScale = d3.scaleTime()
.domain([beginning, ending])
.range([margin.left, width - margin.right]);
const xAxis = d3.axisBottom(xScale)
.tickFormat(tickFormat.format)
.tickSize(tickFormat.tickSize);
if (tickFormat.tickValues != null) {
xAxis.tickValues(tickFormat.tickValues);
} else {
xAxis.ticks(tickFormat.tickTime, tickFormat.tickInterval);
}
// setHeight();
// draw the chart
console.log(g);
g.forEach(function (d, i) {
d = input;
console.log(d);
chartData = d;
// console.log(g._groups[0][0].__data__);
d.forEach(function (datum, index) {
const data = datum.times;
console.log('data');
console.log(data);
const hasLabel = (typeof (datum.label) != 'undefined');
g.selectAll('svg').data(data).enter()
.append(function (d, i) {
return document.createElementNS(d3.namespaces.svg, 'display' in d ? d.display : display);
})
.attr('x', getXPos)
.attr('y', getStackPosition)
.attr('width', function (d, i) {
return (d.ending_time - d.starting_time) * scaleFactor;
})
.attr('cy', function (d, i) {
return getStackPosition(d, i) + itemHeight / 2;
})
.attr('cx', getXPos)
.attr('r', itemHeight / 2)
.attr('height', itemHeight)
.style('fill', function (d, i) {
let dColorPropName;
if (d.color) { return d.color; }
if (colorPropertyName) {
dColorPropName = d[colorPropertyName];
if (dColorPropName) {
return colorCycle(dColorPropName);
} else {
return colorCycle(datum[colorPropertyName]);
}
}
return colorCycle(index);
})
.attr('class', function (d, i) {
return datum.class ? 'timelineSeries_' + datum.class : 'timelineSeries_' + index;
})
.attr('id', function (d, i) {
// use deprecated id field
if (datum.id && !d.id) {
return 'timelineItem_' + datum.id;
}
return d.id ? d.id : 'timelineItem_' + index + '_' + i;
})
;
g.selectAll('svg').data(data).enter()
.append('text')
.attr('x', getXTextPos)
.attr('y', getStackTextPosition)
.text(function (d) {
return d.label;
})
;
// add the label
if (hasLabel) { appendLabel(gParent, yAxisMapping, index, hasLabel, datum); }
if (typeof (datum.icon) !== 'undefined') {
gParent.append('image')
.attr('class', 'timeline-label')
// tslint:disable-next-line:max-line-length
.attr('transform', 'translate(' + 0 + ',' + (margin.top + (itemHeight + itemMargin) * yAxisMapping[index]) + ')')
.attr('xlink:href', datum.icon)
.attr('width', margin.left)
.attr('height', itemHeight);
}
function getStackPosition(d, i) {
if (stacked) {
return margin.top + (itemHeight + itemMargin) * yAxisMapping[index];
}
return margin.top;
}
function getStackTextPosition(d, i) {
if (stacked) {
return margin.top + (itemHeight + itemMargin) * yAxisMapping[index] + itemHeight * 0.75;
}
return margin.top + itemHeight * 0.75;
}
});
});
const belowLastItem = (margin.top + (itemHeight + itemMargin) * maxStack);
const aboveFirstItem = margin.top;
const timeAxisYPosition = showAxisTop ? aboveFirstItem : belowLastItem;
if (showTimeAxis) { appendTimeAxis(g, xAxis, timeAxisYPosition); }
const gSize = g[0][0].getBoundingClientRect();
// console.log('he');
setHeight();
function getXPos(d, i) {
return margin.left + (d.starting_time - beginning) * scaleFactor;
}
function getXTextPos(d, i) {
return margin.left + (d.starting_time - beginning) * scaleFactor + 5;
}
function setHeight() {
if (!height && !gParentItem.attr('height')) {
console.log('itemheight called1' + itemHeight);
if (itemHeight) {
console.log(height);
// set height based off of item height
height = gSize.height + gSize.top - gParentSize.top;
// set bounding rectangle height
// console.log('itemheight called2' + itemHeight);
d3.select(gParent[0][0]).attr('height', height);
} else {
throw new Error('height of the timeline is not set');
}
} else {
// console.log('itemheight called3' + itemHeight);
if (!height) {
// console.log('itemheight called4' + itemHeight);
height = gParentItem.attr('height');
} else {
// console.log('itemheight called5' + itemHeight);
gParentItem.attr('height', height);
}
}
}
function setWidth() {
if (!width && !gParentSize.width) {
try {
width = gParentItem.attr('width');
console.log('width if');
console.log(width);
if (!width) {
// tslint:disable-next-line:max-line-length
throw new Error('width of the timeline is not set. As of Firefox 27, timeline().with(x) needs to be explicitly set in order to render');
}
} catch (err) {
console.log(err);
}
} else if (!(width && gParentSize.width)) {
try {
console.log('width else');
width = gParentItem.attr('width');
console.log(width);
} catch (err) {
console.log(err);
}
}
// if both are set, do nothing
}
}.call(this));