2016-07-07 1 views
0

SVG 맵을 생성하기 위해 노드 기반 명령 행 인터페이스를 구축하고 있습니다. 그러나 Inkscape와 같은 프로그램에서 편집 할 수있는 SVG 파일을 만드는 데 문제가 있습니다. 이는 유틸리티의 유용성을 제한합니다.clipPath 대소 문자를 수정하기 위해 str.replace()를 사용하면 SVG 파일을 편집 할 수 없습니다.

WebKit 오류로 인해 D3에서 생성 된 clipPath 요소가 모두 소문자 clippath 요소가되는데, 이는 물론 적절한 SVG가 아니기 때문에 이미지가 망가질 수 있습니다. 이 문제를 해결하기 위해 글로벌 교체를 수행하여 다시 camelCase로 변환합니다.

이 해결 방법은 브라우저에서 제대로 볼 수있는 SVG 파일을 생성하지만 Inkscape와 같은 SVG 편집 프로그램에서는 편집 할 수 없습니다. 으로 바꾸지 않으면 전역 대체 파일을 편집 할 수 있습니다.

이 문제를 해결하는 방법에 대한 단서가 있습니까?

GitHub의의의 repo, 당신은 CLI를 테스트 할 수 있도록 자신 : https://github.com/hierocles/housemapper-cli

관련 코드 :

function makeMap(fileName) { 
    var document = jsdom.jsdom(); 

    var us = JSON.parse(fs.readFileSync(__dirname + '/jsonfiles/us.json', 'utf8')); 
    var congress = JSON.parse(fs.readFileSync(__dirname + '/jsonfiles/us-cong-114.json', 'utf8')); 

    var css = "<![CDATA[ \ 
     .background { \ 
     fill: none; \ 
     } \ 
     .district { \ 
     fill: #ccc; \ 
     } \ 
     .district-dem-yes { \ 
     fill: #394DE5; \ 
     } \ 
     .district-dem-no { \ 
     fill: #7585FF; \ 
     } \ 
     .district-rep-yes { \ 
     fill: #EA513C; \ 
     } \ 
     .district-rep-no { \ 
     fill: #EA998F; \ 
     } \ 
     .district-yes { \ 
     fill: #03BC82; \ 
     } \ 
     .district-no { \ 
     fill: #3BE2AD; \ 
     } \ 
     .state-boundaries { \ 
     fill: none; \ 
     stroke: #fff; \ 
     stroke-width: 1px; \ 
     } \ 
     .district-boundaries { \ 
     fill: none; \ 
     stroke: #fff; \ 
     stroke-width: 0.5px; \ 
     stroke-linecap: round; \ 
     stroke-linejoin: round; \ 
     }\ 
    ]]>"; 

    var width = 960, 
     height = 500; 

    var projection = d3.geo.albersUsa() 
     .scale(1000) 
     .translate([width/2, height/2]); 

    var path = d3.geo.path() 
     .projection(projection); 

    var svg = d3.select(document.body).append('svg') 
     .attr('xmlns', 'http://www.w3.org/2000/svg') 
     .attr('width', width) 
     .attr('height', height); 

     svg.append("rect") 
      .attr("class", "background") 
      .attr("width", width) 
      .attr("height", height); 

    var defs = svg.append('defs'); 

     defs.append('path') 
     .attr('id', 'land') 
     .datum(topojson.feature(us, us.objects.land)) 
     .attr('d', path); 

     defs.append('style') 
      .attr('type', 'text/css') 
      .text(css); 

     defs.append('clipPath') 
      .attr('id', 'clip-land') 
     .append('use') 
      .attr('xlink:href', '#land'); 

    var g = svg.append('g'); 

     g.attr('clip-path', 'url(#clip-land)') 
     .selectAll('path') 
      .data(topojson.feature(congress, congress.objects.districts).features) 
     .enter().append('path') 
      .attr('d', path) 
      .attr('class', function(d) { return getColor(d); }); 

     g.append('path') 
     .datum(topojson.mesh(congress, congress.objects.districts, function(a, b) { return a !== b && (a.id/1000 | 0) === (b.id/1000 | 0); })) 
     .attr('class', 'district-boundaries') 
     .attr('d', path); 

     g.append('path') 
     .datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; })) 
     .attr('class', 'state-boundaries') 
     .attr('d', path); 

    // This file cannot be edited: 
    var output = d3.select(document.body).html().replace(/clippath/g, 'clipPath'); 

    // This file can be edited: 
    //var output = d3.select(document.body).html(); 

    fs.writeFileSync(fileName, output); 

} 
+0

당신이 연결할 수있는 루트 요소로되는 XLink 네임 스페이스에 추가 예제 SVG 링크 귀하의 프로그램이 생산합니까? "편집 할 수없는"것은 정확히 무슨 뜻입니까? –

+0

수정 된 clipPath : http://dylanist.com/static/output.svg 수정되지 않은 clipPath : http://dylanist.com/static/output2.svg "편집 할 수 없음"이란 말은 예를 들어, Inkscape에서 output.svg를 열면, 나타나는 유일한 모양은 직사각형입니다. 그러나 output2.svg를 열면 올바른 경로 지정없이 모든 경로와 모양이 나타납니다. – hierocles

답변

1

output2.svg에 남아있는 문제는 클립 경로 요소의 <use> 참조하지 않았다이다 옳은.

내가 무슨 짓을 :

  1. <clippath> -><clipPath>
  2. href="#land" ->xlink:href="#land"
  3. <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="960" height="500"> 
    
+0

흠, 확실히 문제가되는 것 같지만 d3/node가 그렇게하는 이유를 알 수 없습니다. 'attr ('xlink : href', '#land')'는 xlink : href 속성을 추가해야하지만 생성 된 SVG는'xlink' 부분을 생략합니다. – hierocles

+0

Google 검색 중 일부는 서버에서 SVG를 렌더링 할 때 네임 스페이스가 제거 된 것처럼 보입니다. 대답은 네임 스페이스 앞에 콜론을 추가하는 것입니다. 다시 말하지만, 왜 그런 일이 벌어지고 있는지 확신 할 수는 없지만 그게 해결책입니다. 잘못된 ''참조를 찾아 주셔서 감사합니다! https://github.com/d3/d3/issues/291#issuecomment-226988829 – hierocles

관련 문제