我刚刚开始使用d3,而js中的相对新手仍在使用。我尝试用线条代替烛台来应用安迪的example。似乎我的函数redrawChart()
无法正常工作。缩放/平移工作但缩放/平移不与我的线路相互作用。
完整代码:
<!DOCTYPE html><meta charset="utf-8">
<style>
#cumul body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
.grid .tick {
stroke: lightgrey;
stroke-opacity: 0.7;
shape-rendering: crispEdges;
}
.grid path {
stroke-width: 0;
}
.navigator .data {
fill: lightgrey;
stroke-width: 0px;
}
.navigator .line {
fill: none;
stroke: darkgrey;
stroke-width: 1px;
}
.navigator .viewport {
stroke: grey;
fill: black;
fill-opacity: 0.2;
}
.chart .overlay {
stroke-width: 0px;
fill-opacity: 0;
}
</style>
<html>
<head>
<!--<script src="d3.min.js" type="text/JavaScript"></script>-->
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
<div id="cumul">
<script>
var margin = { top: 30, right: 50, bottom: 50, left: 50 },
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var navWidth = width,
navHeight = 100 - margin.top - margin.bottom;
var formatDate = d3.time.format("%Y-%m-%d").parse;
var plotChart = d3.select("body").classed('chart', true).append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var plotArea = plotChart.append('g')
.attr('clip-path', 'url(#plotAreaClip)');
plotArea.append('clipPath')
.attr('id', 'plotAreaClip')
.append('rect')
.attr({ width: width, height: height });
var navChart = d3.select("body").classed('chart', true).append('svg')
.classed('navigator', true)
.attr('width', navWidth + margin.left + margin.right)
.attr('height', navHeight + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
d3.json("json.json", 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;
})
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, width]),
yScale = d3.scale.linear()
.domain([yMin, yMax]).nice()
.range([height, 0]);
var navXScale = d3.time.scale()
.domain([minDate, maxDate])
.range([0, navWidth]),
navYScale = d3.scale.linear()
.domain([yMin, yMax])
.range([navHeight, 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')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
plotChart.append("text") // text label for the x axis
.attr("transform", "translate(" + (width / 2) + " ," + (height + margin.bottom) + ")")
.style("text-anchor", "middle")
.text("Dates");
plotChart.append('g')
.attr('class', 'y axis')
.call(yAxis);
plotChart.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Vami");
plotChart.append("text")
.attr("x", (width / 2))
.attr("y", 0 - (margin.top / 2))
.attr("text-anchor", "middle")
.style("font-size", "16px")
.style("text-decoration", "underline")
.text("Value-Added Monthly Index");
var navXAxis = d3.svg.axis()
.scale(navXScale)
.orient('bottom');
navChart.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + navHeight + ')')
.call(navXAxis);
var line = d3.svg.line()
//.interpolate("monotone")
.x(function (d) { return xScale(d.date); })
.y(function (d) { return yScale(d.value); });
var line2 = d3.svg.line()
//.interpolate("monotone")
.x(function (d) { return xScale(d.date); })
.y(function (d) { return yScale(d.valueBchk); });
var line3 = d3.svg.line()
//.interpolate("monotone")
.x(function (d) { return xScale(d.date); })
.y(function (d) { return yScale(d.valueIdx); });
var dataSeries = plotArea.append('g')
.attr('class', 'line')
.datum(data)
.call(line);
var dataSeries2 = plotArea.append('g')
.attr('class', 'line')
.datum(data)
.call(line2);
var dataSeries3 = plotArea.append('g')
.attr('class', 'line')
.datum(data)
.call(line3);
var navData = d3.svg.area()
.x(function (d) { return navXScale(d.date); })
.y0(navHeight)
.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); });
plotChart.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
plotChart.append("text")
.attr("transform", "translate(" + (width + 3) + "," + yScale(data[data.length - 1].value) + ")")
.attr("dy", ".35em")
.attr("text-anchor", "start")
.text("Fund");
//plotChart.append("path")
// .datum(data)
// .attr("class", "line")
// .style("stroke", "red")
// .attr("d", line2);
// plotChart.append("text")
// .attr("transform", "translate(" + (width + 3) + "," + yScale(data[data.length - 1].valueBchk) + ")")
// .attr("dy", ".35em")
// .style("fill", "red")
// .attr("text-anchor", "start")
// .text("Bchk");
// plotChart.append("path")
// .datum(data)
// .attr("class", "line")
// .style("stroke", "blue")
// .attr("d", line3);
// plotChart.append("text")
// .attr("transform", "translate(" + (width + 3) + "," + yScale(data[data.length - 1].valueIdx) + ")")
// .attr("dy", ".35em")
// .style("fill", "blue")
// .attr("text-anchor", "start")
// .text("Idx");
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();
});
var zoom = d3.behavior.zoom()
.x(xScale)
.on('zoom', function () {
if (xScale.domain()[0] < minDate) {
var x = zoom.translate()[0] - xScale(minDate) + xScale.range()[0];
zoom.translate([x, 0]);
} else if (xScale.domain()[1] > maxDate) {
var x = zoom.translate()[0] - xScale(maxDate) + xScale.range()[1];
zoom.translate([x, 0]);
}
redrawChart();
updateViewportFromChart();
});
//x.domain(d3.extent(data, function (d) { return d.date; }));
//y.domain([d3.min(data, function(d) {return Math.min(d.value, d.valueBchk, d.valueIdx); }), d3.max(data, function(d) {return Math.max(d.value, d.valueBchk, d.valueIdx); })]);
navChart.append("g")
.attr("class", "viewport")
.call(viewport)
.selectAll("rect")
.attr("height", navHeight);
var overlay = d3.svg.area()
.x(function (d) { return xScale(d.date); })
.y0(0)
.y1(height);
plotArea.append('path')
.attr('class', 'overlay')
.attr('d', overlay(data))
.call(zoom);
viewport.on("brushend", function () {
updateZoomFromChart();
});
var daysShown = 30;
xScale.domain([
data[data.length - daysShown - 1].date,
data[data.length - 1].date
]);
function redrawChart() {
plotChart.select(".line").attr("d", line);
//dataSeries2.call(line2);
//dataSeries3.call(line3);
plotChart.select('.x.axis').call(xAxis);
}
function updateViewportFromChart() {
if ((xScale.domain()[0] <= minDate) && (xScale.domain()[1] >= 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]);
}
redrawChart();
updateZoomFromChart();
updateViewportFromChart();
});
</script>
</div>
</body>
</html>
以及JSON文件:
[
{
"date": "1998-01-30",
"value": 1000,
"valueBchk": 1000,
"valueIdx": 1000
},
{
"date": "1998-02-28",
"value":1007,
"valueBchk": 1014.9,
"valueIdx": 1066.4
},
{
"date": "1998-03-31",
"value": 1019,
"valueBchk": 1057.5,
"valueIdx": 1110.1
},
{
"date": "1998-04-30",
"value": 1060.3,
"valueBchk": 1037.8,
"valueIdx": 1119.6
},
{
"date": "1998-05-31",
"value": 1077.9,
"valueBchk": 1032.4,
"valueIdx": 1104.3
},
{
"date": "1998-06-30",
"value": 1112.6,
"valueBchk": 1049,
"valueIdx": 1129.2
},
{
"date": "1998-07-31",
"value": 1116.5,
"valueBchk": 1070,
"valueIdx": 1126.1
},
{
"date": "1998-08-31",
"value": 1133.3,
"valueBchk": 1051.1,
"valueIdx": 974.6
},
{
"date": "1998-09-30",
"value": 1158,
"valueBchk": 1045.1,
"valueIdx": 990.5
},
{
"date": "1998-10-31",
"value": 1173.2,
"valueBchk": 1061.2,
"valueIdx": 1078.8
},
{
"date": "1998-11-30",
"value": 1207.6,
"valueBchk": 1092.2,
"valueIdx": 1141.6
},
{
"date": "1998-12-31",
"value": 1252.8,
"valueBchk": 1134.6,
"valueIdx": 1196
},
{
"date": "1999-01-31",
"value": 1286.9,
"valueBchk": 1196.9,
"valueIdx": 1220.9
},
{
"date": "1999-02-28",
"value": 1295.7,
"valueBchk": 1166.1,
"valueIdx": 1187
},
{
"date": "1999-03-31",
"value": 1321.5,
"valueBchk": 1199.8,
"valueIdx": 1235.1
},
{
"date": "1999-04-30",
"value": 1339,
"valueBchk": 1259.7,
"valueIdx": 1282.4
},
{
"date": "1999-05-31",
"value": 1318.1,
"valueBchk": 1243.6,
"valueIdx": 1234.2
},
{
"date": "1999-06-30",
"value": 1290.7,
"valueBchk": 1273.3,
"valueIdx": 1290.4
},
{
"date": "1999-07-31",
"value": 1242.1,
"valueBchk": 1265.6,
"valueIdx": 1285.2
},
{
"date": "1999-08-31",
"value": 1251.9,
"valueBchk": 1267.4,
"valueIdx": 1281.5
},
{
"date": "1999-09-30",
"value": 1316.7,
"valueBchk": 1273.4,
"valueIdx": 1267.7
},
{
"date": "1999-10-31",
"value": 1316.7,
"valueBchk": 1273.4,
"valueIdx": 1267.7
},
{
"date": "1999-11-30",
"value": 1371.6,
"valueBchk": 1288.7,
"valueIdx": 1332.2
},
{
"date": "1999-12-31",
"value": 1397.4,
"valueBchk": 1357.7,
"valueIdx": 1368.4
},
{
"date": "2000-01-31",
"value": 1412,
"valueBchk": 1437,
"valueIdx": 1477.8
},
{
"date": "2000-02-29",
"value": 1443.9,
"valueBchk": 1450.7,
"valueIdx": 1391.9
},
{
"date": "2000-03-31",
"value": 1461,
"valueBchk": 1537,
"valueIdx": 1394.3
},
{
"date": "2000-04-30",
"value": 1531.5,
"valueBchk": 1560.8,
"valueIdx": 1489.3
},
{
"date": "2000-05-31",
"value": 1571.1,
"valueBchk": 1500.7,
"valueIdx": 1425
},
{
"date": "2000-06-30",
"value": 1671.3,
"valueBchk": 1499.7,
"valueIdx": 1387.6
},
{
"date": "2000-07-31",
"value": 1660.3,
"valueBchk": 1507.5,
"valueIdx": 1432.9
},
{
"date": "2000-08-31",
"value": 1671.5,
"valueBchk": 1500.8,
"valueIdx": 1391.2
},
{
"date": "2000-09-30",
"value": 1681.3,
"valueBchk": 1554.6,
"valueIdx": 1435.1
},
{
"date": "2000-10-31",
"value": 1717.5,
"valueBchk": 1551.1,
"valueIdx": 1357.5
}
]
答案 0 :(得分:2)
在redrawChart
功能中,您可以:
plotChart.select(".line").attr("d", line);
这将选择plotChart中第一个带有line类的元素。当您打算使用类别行选择路径时,您已经使用行分类了很多内容,而此选择器正在选择g
元素。
另外,你应该将你的路径追加到plotArea(而不是plotChart),这样它就在剪辑中。
尝试:
plotArea.append("path")
.datum(data)
.attr("class", "myActualLine")
.attr("d", line);
...
function redrawChart() {
plotChart.select(".myActualLine").attr("d", line);
plotChart.select('.x.axis').call(xAxis);
}
完整的工作代码here。