Просто для того, чтобы быть явным. Да, ошибка говорит о том, что вы не можете указывать свой браузер прямо на file://some/path/some.html
. Вот несколько вариантов быстрого развертывания локального веб-сервера, чтобы ваш браузер отображал локальные файлы
Если у вас установлен Python ...
some.html
или файл (ы) существует с помощью команды cd /path/to/your/folder
python -m SimpleHTTPServer
. Это запустит веб-сервер для размещения всего вашего каталога в списке на странице http://localhost:8000
python -m SimpleHTTPServer 9000
, предоставляющий ссылку: http://localhost:9000
Этот подход встроен в любую установку Python.
Выполняйте те же действия, но используйте следующую команду: python3 -m http.server
В качестве альтернативы, если вы требуете более гибкой настройки и уже используете nodejs ...
http-server
, набрав npm install -g http-server
some.html
жизни http-server -c-1
. Это приводит к созданию файла Node.js httpd, который обслуживает файлы в вашем каталоге как статические файлы, доступные из http://localhost:8080
Если ваш предпочтительный язык Ruby ..., то Ruby Gods говорят, что это работает также:
ruby -run -e httpd . -p 8080
Конечно, PHP также имеет свои решение.
php -S localhost:8000
В bl.ocks , который вы ссылаетесь, используется d3.csv
, который (если вы смотрите на docs ), имеет функцию доступа, которая передается каждой строке данных, а затем в обратном вызове обращается вся дата. Вот функция доступа:
function(d) {
d.date = parseDate(d.date);
d.value = +d.value;
return d;
}
Но в случае d3.json нет такого доступа: d3.json(url[, callback])
, что означает, что вам придется анализировать каждую строку в пределах Перезвони. Вот как:
d3.json("test.json", function(data) {
data.forEach(e => {
e.date = parseDate(e.date);
e.value = +e.close;
});
var xExtent = d3.extent(data, function(d) { return d.date; });
.....
Вот вилка вашего кода (я не уверен, почему у вас есть файл с именем api.php, когда он является файлом JSON.Я использовал " test.json ".
Если вы не можете просмотреть это или если вы ищете фрагмент кода, вот один из них:
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 60},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var parseDate = d3.timeParse("%Y-%m-%d"),
formatDate = d3.timeFormat("%Y");
var x = d3.scaleTime()
.domain([new Date(2006, 12, 1), new Date(2007, 1, 1)])
.range([0, width]);
var y = d3.scaleLinear()
.range([height, 0]);
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y);
var area = d3.area()
.curve(d3.curveStepAfter)
.y0(y(0))
.y1(function(d) { return y(d.value); });
var areaPath = g.append("path")
.attr("clip-path", "url(#clip)")
.attr("fill", "steelblue");
var yGroup = g.append("g");
var xGroup = g.append("g")
.attr("transform", "translate(0," + height + ")");
var zoom = d3.zoom()
.scaleExtent([1 / 4, 8])
.translateExtent([[-width, -Infinity], [2 * width, Infinity]])
.on("zoom", zoomed);
var zoomRect = svg.append("rect")
.attr("width", width)
.attr("height", height)
.attr("fill", "none")
.attr("pointer-events", "all")
.call(zoom);
g.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
var data = [{"id":"1","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2006-12-29","time":"15:00:00.000000","close":"2388.023438000000000000","volume":"23700.000000000000000000","active":"1","exchange_id":"0"},{"id":"2","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-04","time":"15:00:00.000000","close":"2416.452637000000000000","volume":"16500.000000000000000000","active":"1","exchange_id":"0"},{"id":"3","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-05","time":"15:00:00.000000","close":"2369.071045000000000000","volume":"45400.000000000000000000","active":"1","exchange_id":"0"},{"id":"4","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-09","time":"15:00:00.000000","close":"2388.023438000000000000","volume":"28800.000000000000000000","active":"1","exchange_id":"0"},{"id":"5","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-10","time":"15:00:00.000000","close":"2369.071045000000000000","volume":"27800.000000000000000000","active":"1","exchange_id":"0"},{"id":"6","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-11","time":"15:00:00.000000","close":"2369.071045000000000000","volume":"25500.000000000000000000","active":"1","exchange_id":"0"},{"id":"7","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-12","time":"15:00:00.000000","close":"2378.546875000000000000","volume":"28100.000000000000000000","active":"1","exchange_id":"0"},{"id":"8","exchange_symbol":"TSE","currency":"JPY","stock_id":"1","stock_name":"KYOKUYO CO.,LTD.","stock_symbol":"1301.T","date":"2007-01-15","time":"15:00:00.000000","close":"2397.500244000000000000","volume":"23400.000000000000000000","active":"1","exchange_id":"0"}];
data.forEach(e => {
e.date = parseDate(e.date);
e.value = +e.close;
});
var xExtent = d3.extent(data, function(d) { return d.date; });
x.domain(xExtent);
zoom.translateExtent([[x(xExtent[0]), -Infinity], [x(xExtent[1]), Infinity]])
y.domain([0, d3.max(data, function(d) { return d.value; })]);
yGroup.call(yAxis).select(".domain").remove();
areaPath.datum(data);
zoomRect.call(zoom.transform, d3.zoomIdentity);
function zoomed() {
var xz = d3.event.transform.rescaleX(x);
xGroup.call(xAxis.scale(xz));
areaPath.attr("d", area.x(function(d) { return xz(d.date); }));
}
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
Надеюсь, это имеет смысл. Кроме того, m, установив домен x
в xExtent
, который вычислен из данных. Поиграйте с ним, чтобы увидеть разницу.
Как-то функция загрузки имеет другой тип и использует следующий формат.
d3.json("api.php", function(data) {
data.forEach(e => {
e.date = parseDate(e.date);
e.value = +e.close;
});
var xExtent = d3.extent(data, function(d) { return d.date; });
zoom.translateExtent([[x(xExtent[0]), -Infinity], [x(xExtent[1]), Infinity]])
y.domain([0, d3.max(data, function(d) { return d.value; })]);
yGroup.call(yAxis).select(".domain").remove();
areaPath.datum(data);
zoomRect.call(zoom.transform, d3.zoomIdentity);
});