質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
SVG

SVGは、XMLを基盤とした2Dベクター画像記述言語。画像を線・面といった図形の集合体として扱うベクター画像のため、環境に適した表示が可能です。アニメーション機能もサポートされており、簡単なインタラクティブコンテンツ作成もできます。

D3.js

D3.jsとは、データに基づいてHTMLやSVGドキュメントを編集するために作られた、小規模なオープンソースのJavaScript可視化ライブラリです。

Safari

SafariはAppleのウェブブラウザであり、Mac OS XとiOSのデフォルトのブラウザです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

2731閲覧

D3.jsのグラフ表示がSafariで上手くできない

poron_poron

総合スコア5

SVG

SVGは、XMLを基盤とした2Dベクター画像記述言語。画像を線・面といった図形の集合体として扱うベクター画像のため、環境に適した表示が可能です。アニメーション機能もサポートされており、簡単なインタラクティブコンテンツ作成もできます。

D3.js

D3.jsとは、データに基づいてHTMLやSVGドキュメントを編集するために作られた、小規模なオープンソースのJavaScript可視化ライブラリです。

Safari

SafariはAppleのウェブブラウザであり、Mac OS XとiOSのデフォルトのブラウザです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2020/01/07 17:30

編集2020/01/08 12:03

前提・実現したいこと

初めての質問のため分かりにくい説明や足らない情報等あるかもしれませんが、ご容赦ください。
Javascriptの勉強を始めて3か月足らずで四苦八苦しております。
サイト内にグラフを描画したかったため、色々調べてD3.jsを利用してSVGにて描画する方法に辿り着き、色んな人のソースを参考にどうにかグラフを表示するところまでこぎつけたのですが、ChromeとfirefoxとAndroidChromeでは表示されるのですが、Safariで表示するとX軸の描画が表示されません。
色々調べてみましたが、ただでさえまだJavascriptの勉強も始めて間もない上にD3.jsのコードもさっぱりで(泣)
説明も下手くそで誠に申し訳ありませんが、ぜひご助言いただければと思っています。
よろしくお願いします!

発生している問題・エラーメッセージ

SafariでX軸の描画がされない(Mac、i-Phone、i-Padともに)

参考になるか分かりませんがSafariのデベロッパーツールでのみコンソールエラーが1件有り

Error

1Error:Problem parsing d3.v5.min.js:2:15853 2d="MNaN,125.093142~長いので中略~190Z"

該当のソースコード

HTML

1<!DOCTYPE html> 2<html lang="jp"> 3<head> 4~中略~ 5 <script src="https://d3js.org/d3.v5.min.js"></script><!-- ←D3.jsの読み込み --> 6</head> 7 8<body> 9<div id="graph-box"> 10 <svg id="graph"></svg> 11</div> 12<script src="./graph.js"></script><!-- ←グラフ描画用読み込み --> 13</body> 14</html>

CSS

1html,body{ 2 margin : 0; 3 padding : 0; 4 width : 100%; 5 height : 100%; 6 overflow : hidden; 7} 8 9/* タイドグラフ部分 */ 10#graph-box, 11#graph-box svg{ 12 margin : 0; 13 padding : 0; 14 width : 100%; 15 height : 100%; 16} 17 18/* 軸のスタイル */ 19g path{ 20 stroke : lightgray; 21 stroke-width : 1px; 22} 23 24/* 罫線スタイル */ 25g.tick line{ 26 stroke : lightgray; 27 stroke-opacity : 0.3; 28 shape-rendering : crispEdges; 29}

JavaScript

1// graph.js 2var data = [ 3 ['2020-01-07 00:00:00', 67.1], 4 ['2020-01-07 00:20:00', 57.8], 5 ['2020-01-07 00:40:00', 49.9], 6 ['2020-01-07 01:00:00', 43.6], 7 ['2020-01-07 01:20:00', 38.9], 8 ['2020-01-07 01:40:00', 35.9], 9 ['2020-01-07 02:00:00', 34.6], 10 ['2020-01-07 02:20:00', 34.9], 11 ['2020-01-07 02:40:00', 37.0], 12 ['2020-01-07 03:00:00', 40.8], 13 ['2020-01-07 03:20:00', 46.4], 14 ['2020-01-07 03:40:00', 53.8], 15 ['2020-01-07 04:00:00', 62.9], 16 ['2020-01-07 04:20:00', 73.6], 17 ['2020-01-07 04:40:00', 85.6], 18 ['2020-01-07 05:00:00', 98.5], 19 ['2020-01-07 05:20:00', 111.9], 20 ['2020-01-07 05:40:00', 125.3], 21 ['2020-01-07 06:00:00', 138.3], 22 ['2020-01-07 06:20:00', 150.6], 23 ['2020-01-07 06:40:00', 161.8], 24 ['2020-01-07 07:00:00', 171.8], 25 ['2020-01-07 07:20:00', 180.5], 26 ['2020-01-07 07:40:00', 187.8], 27 ['2020-01-07 08:00:00', 193.7], 28 ['2020-01-07 08:20:00', 198.3], 29 ['2020-01-07 08:40:00', 201.4], 30 ['2020-01-07 09:00:00', 203.1], 31 ['2020-01-07 09:20:00', 203.2], 32 ['2020-01-07 09:40:00', 201.6], 33 ['2020-01-07 10:00:00', 198.4], 34 ['2020-01-07 10:20:00', 193.7], 35 ['2020-01-07 10:40:00', 187.5], 36 ['2020-01-07 11:00:00', 180.2], 37 ['2020-01-07 11:20:00', 172.1], 38 ['2020-01-07 11:40:00', 163.5], 39 ['2020-01-07 12:00:00', 154.8], 40 ['2020-01-07 12:20:00', 146.4], 41 ['2020-01-07 12:40:00', 138.5], 42 ['2020-01-07 13:00:00', 131.2], 43 ['2020-01-07 13:20:00', 124.6], 44 ['2020-01-07 13:40:00', 118.8], 45 ['2020-01-07 14:00:00', 113.8], 46 ['2020-01-07 14:20:00', 109.6], 47 ['2020-01-07 14:40:00', 106.2], 48 ['2020-01-07 15:00:00', 103.9], 49 ['2020-01-07 15:20:00', 102.8], 50 ['2020-01-07 15:40:00', 103.0], 51 ['2020-01-07 16:00:00', 104.7], 52 ['2020-01-07 16:20:00', 108.0], 53 ['2020-01-07 16:40:00', 112.7], 54 ['2020-01-07 17:00:00', 118.7], 55 ['2020-01-07 17:20:00', 125.8], 56 ['2020-01-07 17:40:00', 133.5], 57 ['2020-01-07 18:00:00', 141.3], 58 ['2020-01-07 18:20:00', 148.9], 59 ['2020-01-07 18:40:00', 155.8], 60 ['2020-01-07 19:00:00', 161.8], 61 ['2020-01-07 19:20:00', 166.6], 62 ['2020-01-07 19:40:00', 170.2], 63 ['2020-01-07 20:00:00', 172.3], 64 ['2020-01-07 20:20:00', 173.1], 65 ['2020-01-07 20:40:00', 172.4], 66 ['2020-01-07 21:00:00', 170.3], 67 ['2020-01-07 21:20:00', 166.5], 68 ['2020-01-07 21:40:00', 161.1], 69 ['2020-01-07 22:00:00', 153.9], 70 ['2020-01-07 22:20:00', 145.1], 71 ['2020-01-07 22:40:00', 134.6], 72 ['2020-01-07 23:00:00', 122.9], 73 ['2020-01-07 23:20:00', 110.3], 74 ['2020-01-07 23:40:00', 97.1], 75 ['2020-01-07 24:00:00', 84.0], 76]; 77 78var margin = {top: -4, right: 0, bottom: 14, left: 24}; 79var width = document.getElementById('graph-box').clientWidth; 80var height = document.getElementById('graph-box').clientHeight; 81 82const svg = d3.select("#graph"); 83 84// X軸の設定 85var x = d3.scaleTime() 86 .domain(d3.extent(data, function(d){ return new Date(d[0]) })) 87 .range([margin.left, width - margin.right]); 88 89// Y軸の設定 90var y = d3.scaleLinear() 91 .domain([-50, 300]) 92 .range([height - margin.bottom, margin.top]); 93 94// X軸を追加 95var xAxis = d3.axisBottom(x).ticks(24, "%H").tickSize(0 - height + margin.bottom + margin.top); 96svg.append("g") 97 .attr("transform", `translate(0,${height - margin.bottom})`) 98 .call(xAxis); 99 100// Y軸を追加 101var yAxis = d3.axisLeft(y).tickSize(0 - width + margin.left + margin.right); 102svg.append("g") 103 .attr("transform", `translate(${margin.left},0)`) 104 .call(yAxis); 105 106// chart描画エリア 107var area = d3.area() 108 .x(function(d){ return x(new Date(d[0]))} ) 109 .y1(function(d){ return y(d[1])} ) 110 .y0(y(-50)); 111 112// pathの設定(各データを描画) 113svg.append("path") 114 .datum(data) 115 .attr("fill", "rgba(70, 130, 180, 0.3)") 116 .attr("d", area);

試したこと

色々なサイトを参考に書き換えたりしてみたのですが効果もなく、お手上げです(泣)

補足情報(FW/ツールのバージョンなど)

D3.jsのバージョンはV5です。
ソースコードは実物になります。長くなってすいません。

ちなみに唯一当方で確認できた部分は、ちゃんと表示されているChromeのデベロッパーツールのElementsでSVGの部分を確認すると下記のように表示されます。

Elements

1<svg id="graph"> 2// X軸の部分? 3<g ~中略~> 4 <path ~中略~></path> 5 <g ~中略~></g> 6 <g ~中略~></g> 7 <g ~中略~></g> 8  ・ 9  ・ 10  ・ 11 <g ~中略~></g> 12</g> 13 14// Y軸の部分? 15<g ~中略~> 16 <path ~中略~></path> 17 <g ~中略~></g> 18 <g ~中略~></g> 19 <g ~中略~></g> 20  ・ 21  ・ 22  ・ 23 <g ~中略~></g> 24</g> 25 26// グラフの部分? 27<path ~中略~></path> 28</svg>

ところが、X軸が表示されないSafariの方を、デベロッパーツールの要素でSVGの部分を確認すると下記のように表示されます。

Elements

1<svg id="graph"> 2// X軸の部分? 3<g ~中略~> 4 <path ~中略~></path> 5/* ここの<g ~中略~></g>の部分が表示されていない! */ 6</g> 7 8// Y軸の部分? 9<g ~中略~> 10 <path ~中略~></path> 11 <g ~中略~></g> 12 <g ~中略~></g> 13 <g ~中略~></g> 14  ・ 15  ・ 16  ・ 17 <g ~中略~></g> 18</g> 19 20// グラフの部分? 21<path ~中略~></path> 22</svg>

X軸部分が描画されていないよねって事なんだと思ってます。
なぜそうなるのかの原因と修正方法がさっぱり分からなくてお手上げ状態です・・・

2020/01/08追記
サンプルを公開しましたので、可能でしたらChromeとiosのSafari(macとかiPhoneとか)とでご確認いただければと思います。
サンプルページ
2020/01/08追記2
解決したのでサンプルページは削除しました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

x軸のスケールは data から min, max を算出してはどうでしょうか。

たとえば、こちらでは、次のように算出しています。

javascript

1// リンク先のコード 2var xScale = d3.scaleTime() 3 .domain([ 4 d3.min(dataset, function(d){return d.date;}), 5 d3.max(dataset, function(d){return d.date;}) 6 ]) 7 .range([padding, width - padding]);

追記)

なぜそうなるのかの原因

エラーとして示された内容として、Path を指定する d属性 の最初の MoveToコマンドで不正な値(NaN)が算出されているようです(MDN:SVG Path 直線コマンドのセクション)。

※ d3.js の 時間軸のスケール指定で使ったAPIが疑わしく思いました。

投稿2020/01/08 07:29

編集2020/01/08 07:43
AkitoshiManabe

総合スコア5432

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

poron_poron

2020/01/08 09:09 編集

ご助言ありがとうございます! 早速いただいた内容で試してみるためスクリプト内の .domain(d3.extent(data, function(d){ return new Date(d[0]) })) の部分を .domain([d3.min(data, function(d){return new Date(d[0]);}), d3.max(data, function(d){return new Date(d[0]);}) ]) のように修正してみたのですが、結果は同じでSafariでのX軸の表示ができませんでした。 もうほんとどうしたものやら・・・
AkitoshiManabe

2020/01/08 09:27

エラーメッセージは 同じだったでしょうか?
poron_poron

2020/01/08 09:43

全く同じでした(泣)
AkitoshiManabe

2020/01/08 09:55

明確な回答には至らないので、コメント欄ですが気になった点を2つ。 1. 日付フォーマットの文字列を内部でDateとして評価してくれそう。 .domain([ d3.min(data,function(d){return d[0]}), d3.max(data,function(d){return d[0]}) ]) 2. 関係なさそうですが、配列要素がオブジェクトのときはどうか? let dataset = data.reduce( (acc, d)=> { acc.push({date:d[0], value:d[1]}); return acc; }, []);
poron_poron

2020/01/08 10:03

早速ありがとうございます! 後で試しにやってみようと思います。 取り急ぎサンプルをUPして見れるようにしましたので、可能でしたらChromeとSafariで見比べてもらえれば現状が分かりやすいかもしれません。 URLはhttp://poronporon.html.xdomain.jp/になります。 よろしくお願いいたしますm(_ _)m
poron_poron

2020/01/08 12:00

先程試してみたところ、配列要素をオブジェクトにしつつ、最初に頂いた参考サイトのソースとにらめっこして修正してみたところ、表示できました!!! コード的には var timeparser = d3.timeParse("%Y-%m-%d %H:%M:%S"); data = data.map(function(d){ return { date: timeparser(d[0]), value:d[1] } ; }); を追加して、domain部分を頂いたものを元に .domain([ d3.min(data, function(d){return d.date;}), d3.max(data, function(d){return d.date;}) ]) に修正したうえで、関係しそうなところを書き換えたらSafariでも表示されました(嬉) 本当に助かりました! 結局Akitoshiさんの気になった点がばっちりはまった感じで感動しました! 大感謝です!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問